To draw arrows in ggplot, I use geom_segment and arrow=arrow(). I would like the arrow head size to match the segment width (or size). However, arrow does not recognize variables directly from the data argument in ggplot and one must specify data.frame containing the variable using the $ operator. This causes a disjunct between the values used for plotting the line and those used for plotting the arrow head (the largest arrow head can be on the thinest segment).
Example:
d <- structure(list(Process = structure(c(2L, 1L, 1L, 1L, 2L, 2L,
1L, 1L, 2L, 1L, 2L), .Label = c("First", "Second"), class = "factor"),
x.sink = c(1, 3, 1, 2, 2, 3, 3, 2, 2, 2, 2), y.sink = c(1,
1, 1, 2, 2, 1, 1, 1, 1, 2, 2), x.source = c(2, 2, 2, 2, 2,
2, 2, 1, 1, 1, 3), y.source = c(2, 2, 2, 1, 1, 1, 1, 1, 1,
2, 1), offset = c(1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1),
Std.Flux = c(0.179487179487179, 0.170940170940171, 0.944444444444444,
0.0854700854700855, 0.726495726495726, 0.128205128205128,
0.213675213675214, 0.213675213675214, 0.128205128205128,
0.106837606837607, 1)), .Names = c("Process", "x.sink", "y.sink",
"x.source", "y.source", "offset", "Std.Flux"), class = "data.frame", row.names = c(NA,
-11L))
p <- qplot(data=d,
#alpha=I(0.4),
colour=Process,
size=Std.Flux,
xlim=c(0,4),
ylim=c(0,3),
x=x.source+as.numeric(Process)/10,
y=y.source+as.numeric(Process)/10,
xend=x.sink+as.numeric(Process)/10,
yend=y.sink+as.numeric(Process)/10,
geom="segment",
arrow = arrow(type="closed",
length = unit(d$Std.Flux,"cm")))
print(p)
Any suggestions?
Parametrization of ggplot2::geom_segment either by location and displacement or by magnitude and angle with default arrows. geom_arrow () is the same as geom_vector () but defaults to preserving the direction under coordinate transformation and different plot ratios. Set of aesthetic mappings created by aes () or aes_ ().
There are three options: If NULL, the default, the data is inherited from the plot data as specified in the call to ggplot (). A data.frame, or other object, will override the plot data. All objects will be fortified to produce a data frame. See fortify () for which variables will be created.
If NULL, the default, the data is inherited from the plot data as specified in the call to ggplot (). A data.frame, or other object, will override the plot data. All objects will be fortified to produce a data frame. See fortify () for which variables will be created.
specification for arrow heads, as created by arrow (). Line end style (round, butt, square). If FALSE, the default, missing values are removed with a warning.
Here's one way:
require(ggplot2)
df <- mtcars
arrow_pos <- data.frame(y = 250)
ggplot(df, aes(x=factor(cyl), y=mpg)) +
geom_bar(width = .4, stat="identity", fill="darkblue") +
geom_segment(data=arrow_pos,
aes(x=1.526, xend=1.01, y=y + 90.02, yend=y + 0.25),
arrow=arrow(length=unit(4.2, "mm")), lwd=2,
color="black") +
geom_segment(data=arrow_pos,
aes(x=1.525, xend=1.01, y=y + 90, yend=y + 0.25),
arrow=arrow(length=unit(4, "mm")), lwd=1,
color="gold2") +
annotate("text", x=2.39, y=360,
label='This arrow points to the highest MPG.') +
scale_y_continuous(limits = c(0,400)) +
xlab('CYL') + ylab('MPG')
Output:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With