使用geom_segment在ggplot中绘制'type = b'-将参数调整为轴比 [英] Plot 'type = b' in ggplot with geom_segment - adjusting parameters to axis ratio

查看:203
本文介绍了使用geom_segment在ggplot中绘制'type = b'-将参数调整为轴比的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于如何使用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...

reprex软件包(v0.2.1)于2019-04-25创建

推荐答案

好吧,除非您使用例如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'-将参数调整为轴比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆