簡體   English   中英

如何在ggplot2中繪制一個漂亮的箭頭

[英]How to draw a nice arrow in ggplot2

我正在創建一個ggplot圖表,我想在兩點之間有一些箭頭。 使用geom_line(arrow = arrow())可以輕松完成主要任務。 但是,我想要一些“漂亮”的粗箭頭。 通過size=調整箭頭size=無濟於事,因為它完全弄亂了箭頭的頭部。 我說明了我的問題:

創建一些示例數據和繪圖:

 NAME <- c("A", "A", "B", "B", "C", "C")
 YEAR <- c(2016, 2011, 2016, 2011, 2016, 2011)
 YEAR <- as.factor(YEAR)
 VALUE <- c(1, 4, 1, 5, 2, 8)
 DATA <- data.frame(NAME, YEAR, VALUE)

ggplot(DATA, aes(x=VALUE, y=NAME)) + 
  geom_point(size=5, aes(colour=YEAR)) +
  geom_line(arrow = arrow(length=unit(0.30,"cm"), ends="first", type = "closed"))

結果圖如下所示:

情節1

現在我試圖“加粗”箭頭......

ggplot(DATA, aes(x=VALUE, y=NAME)) + 
  geom_point(size=5, aes(colour=YEAR)) +
  geom_line(arrow = arrow(length=unit(0.30,"cm"), ends="first", type = "closed"), size = 3)

這是這里顯示的結果:

情節2

我的問題:有沒有辦法繪制一些“漂亮”的粗箭頭?

以下是一些可重現的示例(嘗試運行它們)

一個簡單的箭頭(即線段):

library(dplyr)
library(ggplot2)

# Create a scatter plot
i <- ggplot(mtcars, aes(wt, mpg)) + geom_point()

# Add arrow
i + geom_segment(aes(x = 5, y = 30, xend = 3.5, yend = 25),
                  arrow = arrow(length = unit(0.5, "cm")))

在此處輸入圖片說明

一個簡單的彎曲箭頭

b <- ggplot(mtcars, aes(wt, mpg)) +
  geom_point()

df <- data.frame(x1 = 2.62, x2 = 3.57, y1 = 21.0, y2 = 15.0)

b + geom_curve(
  aes(x = x1, y = y1, xend = x2, yend = y2),
  data = df,
  arrow = arrow(length = unit(0.03, "npc"))
)

在此處輸入圖片說明

可用的箭頭類型

您不必理解此代碼,只需注意可用的lineendlinejoin選項

df2 <- expand.grid(
  lineend = c('round', 'butt', 'square'),
  linejoin = c('round', 'mitre', 'bevel'),
  stringsAsFactors = FALSE
)
df2 <- data.frame(df2, y = 1:9)

ggplot(df2, aes(x = 1, y = y, xend = 2, yend = y, label = paste(lineend, linejoin))) +
  geom_segment(
    lineend = df2$lineend, linejoin = df2$linejoin,
    size = 3, arrow = arrow(length = unit(0.3, "inches"))
  ) +
  geom_text(hjust = 'outside', nudge_x = -0.2) +
  xlim(0.5, 2)

在此處輸入圖片說明

為自己切換的直箭頭

這是一個非常簡單的箭頭來調整每個參數並查看它的作用

ggplot(iris) +
  geom_segment(
    x = 1, y = 1,
    xend = 4, yend = 7,
    lineend = "round", # See available arrow types in example above
    linejoin = "round",
    size = 2, 
    arrow = arrow(length = unit(0.3, "inches")),
    colour = "#EC7014" # Also accepts "red", "blue' etc
  ) + 
  scale_x_continuous(limits = c(0, 10)) +
  scale_y_continuous(limits = c(0, 10))

在此處輸入圖片說明

為自己切換的彎曲箭頭

# Nicer curve
b <- ggplot(mtcars, aes(wt, mpg)) +
  geom_point()

b + geom_curve(
  aes(x = 3, y = 22, xend = 3.5, yend = 15),
  arrow = arrow(
    length = unit(0.03, "npc"), 
                type="closed" # Describes arrow head (open or closed)
    ),
  colour = "#EC7014",
  size = 1.2,
  angle = 90 # Anything other than 90 or 0 can look unusual
)

在此處輸入圖片說明

我通常使用geom_segment來創建箭頭。 但要做到這一點,我們需要從“長”數據修改為“寬”的格式(通常使用dcastreshape2data.table包)。 但是這次我嘗試使用basereshape函數。

ggplot(DATA, aes(x=VALUE, y=NAME)) + 
  geom_point(size=5, aes(colour=YEAR)) +
  geom_segment(data = reshape(DATA, v.names="VALUE", idvar = "NAME", timevar = "YEAR", direction = "wide"),
               aes(x=VALUE.2011, xend=VALUE.2016, y=NAME, yend=NAME), size = 2,
               arrow = arrow(length = unit(0.5, "cm")))

箭頭.segment

編輯:我剛剛發現同樣的問題與“封閉”類型的箭頭有關。 現在,嘗試將繪圖保存為矢量圖(pdf 或 svg,使用 Plots 選項卡中的ggsave或 Export 菜單)。 結果並不“亂”。

svg

在最新的(我的意思是devtools::install_github("tidyverse/ggplot2")最新的,因為寫這個答案-我敢肯定,他們會主線它很快)的版本ggplot2 ,有linejoin參數geom_segment 使用linejoin='mitre'將提供清晰的邊緣。 有關詳細信息,請參閱以下內容

對此有一個非常簡單但有點“hacky”的解決方案。

這個想法是先繪制線條(以所需的粗細,但沒有箭頭),但要短一點(在某些情況下可以計算)。 然后只畫第二條線,不用改變箭頭的大小。 生成的疊加層將看起來像您想要的那樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM