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

标签 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).

附注我知道我可以只在图上方绘制功能区,但是当使用不同的灰度值时,这会变得不太好。再说一次,这个问题更多的是关于如何获得轴比......

reprex package于2019年4月25日创建(v0.2.1)

最佳答案

好吧,除非您手动设置轴比,例如 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中定义。单位,这是一个特殊单位,它告诉图形设备首先计算所有其他元素,并使用剩余空间来放置 null大小的图形元素。

此外,该情节有一个 respect告诉图形设备 null 之间的比率的参数单位应为 1:1 或自由。当存在已知的纵横比时,或者通过 facet_grid(space = ..., scale = ...) ,此参数设置为 true参数。如果respect == TRUE ,然后是高度为 2null 的 grob宽度为1null纵横比将为 2。

grobs$respect
[1] FALSE

我不想给您留下所有坏消息,所以我要指出您也可以在 gtable 中使用这些宽度和高度来根据您的喜好进行设置。

grobs$widths[5]  <- unit(2, "cm")
grobs$heights[7] <- unit(5, "cm")
grid.newpage(); grid.draw(grobs)

enter image description here

这可以帮助您绘制完美的type = b风格图。

离题但与主题无关,回到你之前的问题,我也尝试过对情节进行几何解释(没有成功,所以没有发布它),没有点对点的技巧。我在长宽比方面也遇到了很多麻烦,因为点的确切位置随着设备尺寸的变化而变化。在底层,默认情况下生成图形对象(grobs)的网格包使用标准化父坐标(npc,请参阅 ?unit )。似乎指向正确方向的一件事正在转换您命名的 hyp - param相当于unit(hyp, "npc") - convertUnit(unit(param, "mm"), "npc", axisFrom = "y", typeFrom = "dimension") (对于 y 轴,我已经使用 npc 单位作为我的坐标)。现在我无法正确实现这一点,但也许它会帮助您获得一些想法。

关于r - 使用 geom_segment 在 ggplot 中绘制 'type = b' - 调整轴比参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55853359/

相关文章:

r - 绘制多个图的平均值的图

r - 如何选择比较具有相同值的多列的行?

r - 如何在igraph中设置Louvain模块化的分辨率参数?

r - 在R中对箱线图标注离群值

使用正则表达式对 R 行数据框中的值重新排序

string - 用 Latex 代码替换字符串向量中的重音符号

r - dplyr + magrittr + qplot = 没有情节?

r - 如何将图例值显示为百分比

R:将 alpha 包添加到 2d 或 3d 散点图

r - 用 ggplot2 直方图中另一个连续变量的平均值填充条形颜色