使用geom_segment在ggplot中绘制'type = b'-将参数调整为轴比

时间:2019-04-25 15:58:40

标签: r ggplot2

围绕如何使用ggplot创建“ type = b”外观存在一些问题(例如herehere) 当前最好的解决方案是简单地在基础背景的颜色上创建较大的点-很简单。 我正在寻找使用geom_segment的解决方案-因为当前的解决方案不允许额外的“幻想”,尤其是:错误带。请参阅底部的图。 (我知道我可以使用行作为置信区间,这看起来不错,但是问题在于下面的问题

我使用基本三角函数做了一个简单的函数,以便计算geom_segment中各段的x和y(请参阅下文-感谢@moody_mudskipper给出了如何实现这一点的主要思想)。现在,仅适用于coord_equal (请参见下文)。我的问题是,如何从创建的绘图中获取轴比率,以便使用该比率来计算x / y分段?

   
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 的图-确实不起作用

p1
#> Warning: Removed 11 rows containing missing values (geom_segment).

使用coord_equal 进行绘图-给出正确的细分

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。我知道我可以在功能区上方绘制功能区,但是使用不同的灰度值时,效果会不太好。再说一次,这个问题更多地是关于如何获得轴比...

reprex package(v0.2.1)于2019-04-25创建

1 个答案:

答案 0 :(得分:3)

好吧,除非您用theme(aspect.ratio ...)coord_fixed()手动设置轴比,否则就不能这样做,因为曲线图是根据设备的尺寸来调整其位置的。

要对此进行检查,您可以使用ggplotGrob(myplot)将图制作成gtable并查看布局,该图形对象是面板。

g <- ggplot(pressure, aes(temperature, pressure)) +
  geom_point()

grobs <- ggplotGrob(g)

在该布局中,您可以看到面板的t(顶部)和l(左侧)位置。

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。

grobs$widths[5]
[1] 1null
grobs$heights[7]
[1] 1null

面板的高度和宽度通常以null单位定义,这是一种特殊的单位,它告诉图形设备首先计算所有其他元素,然后使用剩余的空间放置{{1} }大小的图形元素。

此外,该图具有一个null参数,该参数告诉图形设备respect单位之间的比率应为1:1还是自由的。当存在已知的宽高比时,或通过null参数将此参数设置为true。如果为facet_grid(space = ..., scale = ...),则高度为respect == TRUE且宽度为2null的小工具的长宽比将为2。

1null
grobs$respect

我不想给您留下所有坏消息,所以我要指出的是,您也可以使用gtable中的这些宽度和高度将它们设置为您喜欢的样式。

[1] FALSE

enter image description here

这可以帮助您绘制出完美的grobs$widths[5] <- unit(2, "cm") grobs$heights[7] <- unit(5, "cm") grid.newpage(); grid.draw(grobs) 样式图。

离题但切线相关,回到您先前的问题时,我也可以对绘图进行几何解释(未成功完成,所以没有发布),没有指向对点的技巧。高宽比也给我带来了很多麻烦,因为这些点的确切位置在设备尺寸上发生了变化。在底层,默认情况下用于制作图形对象(抓点)的网格包使用归一化的父坐标(npc,请参见type = b)。似乎指向正确的方向是将您命名的?unithyp - param等效(对于y轴,我已经在使用unit(hyp, "npc") - convertUnit(unit(param, "mm"), "npc", axisFrom = "y", typeFrom = "dimension")单位坐标)。现在我无法正确实现此功能,但是也许可以帮助您获得一些想法。