Consider for example this plot using the data mtcars
and the function coord_flip
例如,考虑使用数据mtcars和函数coord_flip的这个图
library(ggplot2)
library(Hmisc)
ggplot(mtcars,aes(x=gear,y=cyl)) + stat_summary(aes(color=as.factor(rep(1:2,16))),
fun.data=mean_cl_boot, position=position_dodge(0.4)) + coord_flip()
The fact that error bars are horizontal on the graph but vertical in the legend bothers me :) How can I rotate these symbols?
错误栏在图表上是水平但在图例中垂直的事实困扰我:)我如何旋转这些符号?
3 个解决方案
#1
3
I'm not coming up with an answer that works within the normal ggplot2 workflow, so for now, here's a hacky answer. Turn off the stat_summary
legend. Then, add point and line geoms with data that is outside the range of the actual data you want to plot. This will create the point and horizontal line legend that you want. Then set the plot axis limits to include only the range of your real data, so that the fake data points are not visible.
我没有想出一个在正常的ggplot2工作流程中有效的答案,所以现在,这是一个hacky的答案。关闭stat_summary图例。然后,使用超出要绘制的实际数据范围的数据添加点和线主题。这将创建所需的点和水平线图例。然后将绘图轴限制设置为仅包括实际数据的范围,以便伪数据点不可见。
ggplot(mtcars, aes(x=gear, y=cyl, color=as.factor(rep(1:2,16)))) +
stat_summary(fun.data=mean_cl_boot, position=position_dodge(0.4), show.legend=FALSE) +
geom_line(aes(y=cyl-100)) +
geom_point(aes(y=cyl-100), size=2.5) +
coord_flip(ylim=range(mtcars$cyl))
Another option would be to rotate the legend-key grobs by 90 degrees using grid functions, but I'll leave that for someone who's more skilled with grid
than I am.
另一个选择是使用网格函数将图例键的凹凸旋转90度,但我会留给那些比我更熟练的格栅的人。
#2
5
Tweak the legend key
调整图例键
GeomPointrange$draw_key <- function (data, params, size) {
draw_key_vpath <- function (data, params, size) {
# only need to change the x&y coords so that the line is horizontal
# originally, the vertical line was `0.5, 0.1, 0.5, 0.9`
segmentsGrob(0.1, 0.5, 0.9, 0.5,
gp = gpar(col = alpha(data$colour, data$alpha),
lwd = data$size * .pt, lty = data$linetype,
lineend = "butt"), arrow = params$arrow)
}
grobTree(draw_key_vpath(data, params, size),
draw_key_point(transform(data, size = data$size * 4), params))
}
Then plot
然后情节
ggplot(mtcars,aes(x=gear,y=cyl)) +
stat_summary(aes(color=as.factor(rep(1:2,16))),
fun.data=mean_cl_boot, position=position_dodge(0.4)) +
coord_flip()
#3
2
Following up @eipi10's suggestion to use grid
functions to edit the grobs - the relevant grobs are segments. There are two possibilities: 1) rotate the segment grobs; or 2) edit the x and y coordinates of the endpoints of the segment grobs.
继续@ eipi10建议使用网格函数来编辑grobs - 相关的grob是段。有两种可能性:1)旋转节段凹凸;或者2)编辑段grobs的端点的x和y坐标。
library(ggplot2)
library(Hmisc)
library(grid)
p = ggplot(mtcars,aes(x=gear,y=cyl)) +
stat_summary(aes(color=as.factor(rep(1:2,16))),
fun.data=mean_cl_boot, position=position_dodge(0.4)) +
coord_flip()
g = ggplotGrob(p)
# Get names of segment grobs
grid.ls(grid.force(g))$name # "GRID.segments"
# Check the structure of the segment grobs
str(getGrob(grid.force(g), gPath("GRID.segments"), grep = TRUE, global = TRUE))
# Edit the segment grobs using the editGrob() function
# 1) Rotate the segments
g <- editGrob(grid.force(g), gPath("GRID.segments"), grep = TRUE, global = TRUE,
vp = viewport(angle = 90))
# 2) set end points of segments
# g <- editGrob(grid.force(g), gPath("GRID.segments"), grep = TRUE, global = TRUE,
# x0 = unit(0.1, "npc"), y0 = unit(0.5, "npc"), x1 = unit(0.9, "npc"), y1 = unit(0.5, "npc"))
# Draw it
grid.newpage()
grid.draw(g)
#1
3
I'm not coming up with an answer that works within the normal ggplot2 workflow, so for now, here's a hacky answer. Turn off the stat_summary
legend. Then, add point and line geoms with data that is outside the range of the actual data you want to plot. This will create the point and horizontal line legend that you want. Then set the plot axis limits to include only the range of your real data, so that the fake data points are not visible.
我没有想出一个在正常的ggplot2工作流程中有效的答案,所以现在,这是一个hacky的答案。关闭stat_summary图例。然后,使用超出要绘制的实际数据范围的数据添加点和线主题。这将创建所需的点和水平线图例。然后将绘图轴限制设置为仅包括实际数据的范围,以便伪数据点不可见。
ggplot(mtcars, aes(x=gear, y=cyl, color=as.factor(rep(1:2,16)))) +
stat_summary(fun.data=mean_cl_boot, position=position_dodge(0.4), show.legend=FALSE) +
geom_line(aes(y=cyl-100)) +
geom_point(aes(y=cyl-100), size=2.5) +
coord_flip(ylim=range(mtcars$cyl))
Another option would be to rotate the legend-key grobs by 90 degrees using grid functions, but I'll leave that for someone who's more skilled with grid
than I am.
另一个选择是使用网格函数将图例键的凹凸旋转90度,但我会留给那些比我更熟练的格栅的人。
#2
5
Tweak the legend key
调整图例键
GeomPointrange$draw_key <- function (data, params, size) {
draw_key_vpath <- function (data, params, size) {
# only need to change the x&y coords so that the line is horizontal
# originally, the vertical line was `0.5, 0.1, 0.5, 0.9`
segmentsGrob(0.1, 0.5, 0.9, 0.5,
gp = gpar(col = alpha(data$colour, data$alpha),
lwd = data$size * .pt, lty = data$linetype,
lineend = "butt"), arrow = params$arrow)
}
grobTree(draw_key_vpath(data, params, size),
draw_key_point(transform(data, size = data$size * 4), params))
}
Then plot
然后情节
ggplot(mtcars,aes(x=gear,y=cyl)) +
stat_summary(aes(color=as.factor(rep(1:2,16))),
fun.data=mean_cl_boot, position=position_dodge(0.4)) +
coord_flip()
#3
2
Following up @eipi10's suggestion to use grid
functions to edit the grobs - the relevant grobs are segments. There are two possibilities: 1) rotate the segment grobs; or 2) edit the x and y coordinates of the endpoints of the segment grobs.
继续@ eipi10建议使用网格函数来编辑grobs - 相关的grob是段。有两种可能性:1)旋转节段凹凸;或者2)编辑段grobs的端点的x和y坐标。
library(ggplot2)
library(Hmisc)
library(grid)
p = ggplot(mtcars,aes(x=gear,y=cyl)) +
stat_summary(aes(color=as.factor(rep(1:2,16))),
fun.data=mean_cl_boot, position=position_dodge(0.4)) +
coord_flip()
g = ggplotGrob(p)
# Get names of segment grobs
grid.ls(grid.force(g))$name # "GRID.segments"
# Check the structure of the segment grobs
str(getGrob(grid.force(g), gPath("GRID.segments"), grep = TRUE, global = TRUE))
# Edit the segment grobs using the editGrob() function
# 1) Rotate the segments
g <- editGrob(grid.force(g), gPath("GRID.segments"), grep = TRUE, global = TRUE,
vp = viewport(angle = 90))
# 2) set end points of segments
# g <- editGrob(grid.force(g), gPath("GRID.segments"), grep = TRUE, global = TRUE,
# x0 = unit(0.1, "npc"), y0 = unit(0.5, "npc"), x1 = unit(0.9, "npc"), y1 = unit(0.5, "npc"))
# Draw it
grid.newpage()
grid.draw(g)