[英]How to draw a nice arrow in ggplot2
I am creating a ggplot
chart where I want to have some arrows between two points.我正在创建一个
ggplot
图表,我想在两点之间有一些箭头。 The main task is easily done with geom_line(arrow = arrow())
.使用
geom_line(arrow = arrow())
可以轻松完成主要任务。 However, I want to have some "beautiful" thick arrows.但是,我想要一些“漂亮”的粗箭头。 Resizing the arrow via
size=
doesn't help since it messes up the head of the arrow completely.通过
size=
调整箭头size=
无济于事,因为它完全弄乱了箭头的头部。 I illustrate my Problems:我说明了我的问题:
Create some sample data and a plot:创建一些示例数据和绘图:
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"))
The resulting plot looks like that:结果图如下所示:
Now I've tried to "thicken" the arrows...现在我试图“加粗”箭头......
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)
That's the result shown here:这是这里显示的结果:
My question: Is there any way to plot some "beautiful" thick arrows?我的问题:有没有办法绘制一些“漂亮”的粗箭头?
Here are some reproducible examples (try running them)以下是一些可重现的示例(尝试运行它们)
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"))
)
You don't have to understand this code, but simply note the lineend
, and linejoin
options available to you您不必理解此代码,只需注意可用的
lineend
和linejoin
选项
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)
Here is a very simple arrow to adjust each parameter and see what it does这是一个非常简单的箭头来调整每个参数并查看它的作用
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
)
I usually use geom_segment
to create arrow.我通常使用
geom_segment
来创建箭头。 But to do that we need to modify the data from "long" to "wide" format (usually using dcast
from reshape2
or data.table
package).但要做到这一点,我们需要从“长”数据修改为“宽”的格式(通常使用
dcast
从reshape2
或data.table
包)。 But this time I tried using base
's reshape
function.但是这次我尝试使用
base
的reshape
函数。
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")))
EDIT : I just found that same issue pertains for "closed" type arrows.编辑:我刚刚发现同样的问题与“封闭”类型的箭头有关。 For now, try to save the plot as a vector graph (pdf or svg, using
ggsave
or Export menu in Plots tab).现在,尝试将绘图保存为矢量图(pdf 或 svg,使用 Plots 选项卡中的
ggsave
或 Export 菜单)。 The result is not "messy".结果并不“乱”。
In the latest (and I mean devtools::install_github("tidyverse/ggplot2")
latest, as of writing this answer - I'm sure they'll mainline it soon enough) version of ggplot2
, there is a linejoin
argument to geom_segment
.在最新的(我的意思是
devtools::install_github("tidyverse/ggplot2")
最新的,因为写这个答案-我敢肯定,他们会主线它很快)的版本ggplot2
,有linejoin
参数geom_segment
。 Using linejoin='mitre'
will provide crisp edges.使用
linejoin='mitre'
将提供清晰的边缘。 See the following for details .有关详细信息,请参阅以下内容。
There is a very simple, but somewhat "hacky" solution to this.对此有一个非常简单但有点“hacky”的解决方案。
The idea is to draw the lines first (at the desired thickness, but no arrowheads), but a little bit shorter (can be calculated in some cases).这个想法是先绘制线条(以所需的粗细,但没有箭头),但要短一点(在某些情况下可以计算)。 Then just draw a second line, without changing the size with arrowheads.
然后只画第二条线,不用改变箭头的大小。 The resulting overlay will look the way you want.
生成的叠加层将看起来像您想要的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.