r - 自动将 y 轴文本和网格线对齐到 ggplot 的底部和顶部

标签 r ggplot2

我们公司的图表布局基于 Excel。在 Excel 中,默认情况下,y 轴文本和网格线从图表底部开始,到图表顶部结束。使用 R 和 ggplot2,默认行为似乎只显示数据的最小值和最大值之间的标签。

手动,我会像下面的例子一样使用限制来达到预期的结果。但是,有没有办法自动实现这种行为?对每个图表手动执行此操作不是一种选择,因为我们有数百个图表,其中数据随时间变化。

library( ggplot2 )

# transform data to make the problem more obvious
df <- cars
df$speed  <- df$speed + 4

# default ggplot behaviour: y-axis grid lines and ticks are placed where they fit best
ggplot( df, aes( x = dist, y = speed ) ) + 
  geom_line() +
  ggtitle( "Default behavior: y-axis grid lines and text inside data-range" ) +
  scale_y_continuous( expand = c( 0, 0 ) ) +
  theme( panel.background    = element_rect( fill   = "white" ),
         panel.border        = element_blank(),
         panel.grid.major.y  = element_line( colour = "#d9d9d9",
                                             size   = 0.001 ),
         axis.ticks.x        = ggplot2::element_line( color = "#d9d9d9" ),
         axis.ticks.y        = ggplot2::element_blank() )

# desired outcome: y-axis text and grid lines start at bottom and end at top (achieved with expand and limits)
ggplot( df, aes( x = dist, y = speed ) ) + 
  geom_line() +
  ggtitle( "Disired outcome: y-axis grid lines and text at bottom and top" ) +
  scale_y_continuous( expand = c( 0, 0 ), 
                      limits = c( 5, 30 ) ) +
  theme( panel.background    = element_rect( fill   = "white" ),
         panel.border        = element_blank(),
         panel.grid.major.y  = element_line( colour = "#d9d9d9",
                                             size   = 0.001 ),
         axis.ticks.x        = ggplot2::element_line( color = "#d9d9d9" ),
         axis.ticks.y        = ggplot2::element_blank() )

默认的 ggplot2 行为:请注意 y 轴文本和网格线未与图表的底部和顶部对齐

Default ggplot2 behavior: note that y-axis text and grid-lines are not aligned to bottom and top of the chart

期望的结果:y 轴文本和网格线位于图表的底部和顶部(值 5 和 30)

Desired outcome: y-axis text and grid-lines are at the bottom and top of the chart (values 5 and 30)

最佳答案

因为比例尺的 limits 参数可以接受将应用于数据范围的函数,所以我们可以创建一个自动将限制设置为更好数字的函数。这是您可以使用的示例函数,但我没有针对所有可能的情况测试它。

library( ggplot2 )

# transform data to make the problem more obvious
df <- cars
df$speed  <- df$speed + 4

nicelimits <- function(x) {
  # x is the range of the data
  # get breaks under default breaks behaviour (breaks are not known in advance)
  breaks <- scales::extended_breaks()(x)
  # Take the difference between breaks (should be constant)
  width  <- diff(breaks)[1]
  # Do something like `floor()`, but with `width`-units
  start <- (x[1] %/% width) * width
  # Do something like `ceiling()`, but with `width`-units
  end <- (c(x[2] %/% width) + 1) * width
  c(start, end)
}


ggplot( df, aes( x = dist, y = speed ) ) + 
  geom_line() +
  scale_y_continuous( expand = c( 0, 0 ),
                      limits = nicelimits) +
  theme( panel.background    = element_rect( fill   = "white" ),
         panel.border        = element_blank(),
         panel.grid.major.y  = element_line( colour = "#d9d9d9",
                                             size   = 0.001 ),
         axis.ticks.x        = ggplot2::element_line( color = "#d9d9d9" ),
         axis.ticks.y        = ggplot2::element_blank() )

reprex package 创建于 2020-12-20 (v0.3.0)

编辑:正如评论中的@stefan 指出的那样,这也将成为很好的限制并且更少的自定义代码:

nicelimits <- function(x) {
  range(scales::extended_breaks(only.loose = TRUE)(x))
}

我注意到的一个区别是,如果上限处于中断状态,第一个函数会将上限扩展 + width,而在这种情况下,后一个函数将返回自然上限。

关于r - 自动将 y 轴文本和网格线对齐到 ggplot 的底部和顶部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65378370/

相关文章:

r - 为什么模式适用于 str_extract_all 但不适用于 strsplit 或 str_subset?

r - 将 exp/power 趋势线添加到 ggplot

r - 如何在ggplot2中使轴刻度线朝内

r - 密度曲线下的阴影(填充或颜色)面积(按分位数)

r - 如何在 R 中绘制多个函数?

r - 在 quantstrat 中执行止损限价订单时出错

r - 如何使用GGPLOT Facet创建4x4散点图

r - 如何在R中的绘图中添加一条线

r - 用利率向量计算复利

r - ggplot条形图中的水平白线