问题描述
关于如何使用ggplot创建"type = b"外观存在一些问题(例如这里和这里)当前最好的解决方案是简单地在底层背景的颜色中创建较大的点-公认非常简单.我正在寻找使用geom_segment
的解决方案-因为当前的解决方案不允许额外的幻想",尤其是:错误带.请参阅底部的图. (我知道我可以使用行作为置信区间,这看起来不错,但是问题在于下面的问题)
There are a few questions around how to create a 'type = b' look with ggplot (e.g. here and here)The currently best solution is simply creating bigger dots in the color of the underlying background - which is admittedly very straight forward.I am looking for a solution with geom_segment
- because the current solution does not allow for additional 'fanciness', in particular: error bands. See graph at the bottom. (I know that I can use lines for the confidence intervals, and this looks good, but the question is regarding the below)
我使用基本三角函数做了一个简单的函数,以便计算geom_segment
中各段的x和y(请参见下文-感谢@moody_mudskipper给出了如何实现这一点的主要思想).现在,仅适用于coord_equal
(请参见下文).我的问题是,如何从创建的绘图中获取轴比率,以便使用该比率来计算x/y分段?
I have made a simple function using basic trigonometry in order to calculate x and y for the segments in geom_segment
(see below - thanks to @moody_mudskipper to give the main ideas how to approach this). Now, this only works with coord_equal
(see below). My question is, how can I obtain the axis ratio from the plot which is created in order to use this ratio for calculation of the x/y segments?
library(ggplot2)
# function to get data frame with x and y parameters for geom_segment
get_segments <- function(df, x, y, param){
# hyp = hypotenuse of right triangle between x and y of dot plot
# sin_plot and cos_plot = sine and cosine of right triangle of dot plot
# diff_..._seg = hypotenuse of segment added to main dot plot
x <- df[[deparse(substitute(x))]]
y <- df[[deparse(substitute(y))]]
hyp <-sqrt(diff(x)^2 + diff(y)^2)
sin_plot <- diff(y) / hyp
cos_plot <- diff(x) / hyp
diff_x1_seg <- param * cos_plot
diff_x2_seg <- (hyp-param) * cos_plot
diff_y1_seg <- param * sin_plot
diff_y2_seg <- (hyp-param) * sin_plot
x1 <- c(head(x,-1) + diff_x1_seg)
x2 <- c(head(x,-1) + diff_x2_seg)
y1 <- c(head(y,-1) + diff_y1_seg)
y2 <- c(head(y,-1) + diff_y2_seg)
plot_data <- data.frame(x1,x2,y1,y2)
plot_data$x1 <- ifelse(plot_data$x1 > plot_data$x2, NA, x1)
plot_data
}
# Using the function on sample data
plot_data <-
get_segments(pressure, x = temperature, y = pressure, 15)
# Making the plot
p1 <- ggplot(pressure, aes(temperature, pressure)) +
geom_point() +
geom_segment(data = plot_data, mapping = aes(x = x1, xend = x2, y = y1, yend = y2))
没有coord_equal
的图-确实不起作用
Plot without coord_equal
- does not really work
p1
#> Warning: Removed 11 rows containing missing values (geom_segment).
用coord_equal
绘制-给出正确的细分
Plot with coord_equal
- gives the right segments
p1 + coord_equal()
#> Warning: Removed 11 rows containing missing values (geom_segment).
示例可能不错的示例:
ggplot(pressure, aes(temperature, pressure)) +
geom_ribbon(aes(ymin = pressure - 50, ymax = pressure + 50), alpha = 0.2) +
geom_point() +
geom_segment(data = plot_data, mapping = aes(x = x1, xend = x2, y = y1, yend = y2))
#> Warning: Removed 11 rows containing missing values (geom_segment).
P.S.我知道我可以在功能区上方绘制功能区,但是当使用不同的灰度值时,效果会变差.再说一次,这个问题更多地是关于如何获得轴比的...
P.S. I know that I could just plot the ribbon above the plot, but this gets less nice when using different grey values. And again, this question is more about how to get the axis ratio...
推荐答案
好吧,除非您使用例如theme(aspect.ratio ...)
或coord_fixed()
手动设置轴比,否则,因为绘图会根据设备的大小.
Well, unless you manually set the axis ratio with for example theme(aspect.ratio ...)
, or coord_fixed()
you can't, since the plots adjust their positioning based on the size of the device.
要对此进行检查,您可以通过ggplotGrob(myplot)
将图制作成gtable并查看布局,该图形对象是面板.
To check this, you can make your plot into a gtable by ggplotGrob(myplot)
and look at the layout what graphical object is the panel.
g <- ggplot(pressure, aes(temperature, pressure)) +
geom_point()
grobs <- ggplotGrob(g)
在该布局中,您可以看到面板的t(顶部)和l(左侧)位置.
In that layout you can see the t (top) and l (left) position of the panel.
head(grobs$layout)
t l b r z clip name
18 1 1 12 9 0 on background
1 6 4 6 4 5 off spacer
2 7 4 7 4 7 off axis-l
3 8 4 8 4 3 off spacer
4 6 5 6 5 6 off axis-t
5 7 5 7 5 1 on panel
您可以在上方看到该面板是列表中的第六个类别,其高度为7,宽度为5.
You can see above that the panel is the sixth grob in the list and has position 7 of the heights and position 5 of the widths.
grobs$widths[5]
[1] 1null
grobs$heights[7]
[1] 1null
面板的高度和宽度通常以null
单位定义,这是一种特殊的单位,它告诉图形设备首先计算所有其他元素,然后使用剩余的空间放置null
尺寸的图形元素.
The height and width of panels are usually defined in null
units, which is a special unit that kind of tells the graphics device to calculate all other elements first and use the leftover space to place the null
-sized graphical elements.
此外,该图具有一个respect
参数,该参数告诉图形设备null
单位之间的比率应为1:1还是自由.当存在已知的宽高比时,或通过facet_grid(space = ..., scale = ...)
参数将此参数设置为true.如果为respect == TRUE
,则高度为2null
且宽度为1null
的笔触的长宽比为2.
Furthermore, the plot has a respect
parameter that tells the graphics device wether the ratio between null
units should be 1:1 or are free. This parameters is set to true when there is a known aspect ratio, or by facet_grid(space = ..., scale = ...)
parameters. If respect == TRUE
, then a grob with a height of 2null
and a width of 1null
will have an aspect ratio of 2.
grobs$respect
[1] FALSE
我不想给您留下所有坏消息,所以我要指出的是,您也可以使用gtable中的这些宽度和高度将它们设置为您喜欢的样式.
I don't want to leave you with all bad news so I'm gonna point out that you can also use these widths and heights in the gtable to set them to your liking.
grobs$widths[5] <- unit(2, "cm")
grobs$heights[7] <- unit(5, "cm")
grid.newpage(); grid.draw(grobs)
这可以帮助您绘制出完美的type = b
样式图.
Which could help you plot the perfect type = b
style plots.
离题但切线相关,回到您先前的问题时,我还可以对绘图进行几何解释(未成功完成,所以没有发布),没有指向对点的技巧.高宽比也给我带来了很多麻烦,因为这些点的确切位置在设备尺寸上发生了变化.在底层,默认情况下用于制作图形对象(毛刺)的网格包使用归一化的父坐标(npc,请参见?unit
).似乎朝着正确方向的事情是,将您命名为hyp - param
的内容转换为与unit(hyp, "npc") - convertUnit(unit(param, "mm"), "npc", axisFrom = "y", typeFrom = "dimension")
等效的内容(对于y轴,我已经在使用npc
单位作为坐标了).现在我无法正确实现此功能,但是也许可以帮助您获得一些想法.
Off-topic but tangentially related, back at your previous question I also had a go at making the geometric interpretation of the plot (wasn't succesfull so didn't post it), without the point over point trick. I also had a lot of trouble with the aspect ratio, since the exact placing of the points changed on the device size. Under the hood, the grid package that makes graphical objects (grobs) by default use normalised parent coordinates (npc, see ?unit
). A thing that seemed to be pointing in the right direction was converting what you named hyp - param
with the equivalent of unit(hyp, "npc") - convertUnit(unit(param, "mm"), "npc", axisFrom = "y", typeFrom = "dimension")
(for the y-axis, I was already working with npc
units for my coordinates). Now I wasn't able to implement this properly, but maybe it would help you get some ideas.
这篇关于使用geom_segment在ggplot中绘制'type = b'-将参数调整为轴比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!