如何为ggplot2对象提取绘图轴的范围?


88

我有一个物体ggplot2,比如说myPlot,如何确定x和y轴的范围?

它似乎不是数据值范围的简单倍数,因为它可以重新缩放绘图,修改轴的范围等等。 findFn(来自sos)和Google似乎没有找到相关结果,除了如何设置坐标轴的范围。


1
我相当确定不能直接从plot对象本身中提取出来,但是可以从您的数据和的默认值中推断出来(在简单情况下)expand。看这里
joran 2011年

1
我指的expand是中scale_*函数的参数ggplot。例如,请参阅此处列出的默认值。
joran 2011年

6
您将可以在下一个版本中提取它……
hadley 2011年

1
您能接受Alex Holcombe的回答吗?保罗·海姆斯特拉(Paul Hiemstra)仅与三年前的ggplot2版本相关。
Max Ghenis 2015年

4
**截至2018年8月,您使用以下内容提取x和y轴范围。** ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
迈克尔

Answers:


41

在较新版本的ggplot2中,您可以在的输出中找到此信息ggplot_build(p)pggplot对象在哪里。

对于旧版本的ggplot(<0.8.9),以下解决方案有效:

在Hadley发行新版本之前,这可能会有所帮助。如果未在绘图中设置限制,则ggplot对象中将没有任何信息。但是,在这种情况下,您可以使用ggplot2的默认值并从数据中获取xlim和ylim。

> ggobj = ggplot(aes(x = speed, y = dist), data = cars) + geom_line()
> ggobj$coordinates$limits

$x
NULL

$y
NULL

设置限制后,这些限制将在对象中变为可用:

> bla = ggobj + coord_cartesian(xlim = c(5,10))
> bla$coordinates$limits
$x
[1]  5 10

$y
NULL

34
具体来说,在较新版本的ggplot2中,您可以使用ggplot_build(ggobj)$ panel $ ranges [[1]] $ y.range和y范围使用ggplot_build(ggobj)$ panel $ ranges [[1]] $获得yrange x.range
Alex Holcombe

11
对于ggplot22.1.0.9001版本,请使用以下R代码: ggplot_build(obj)$layout$panel_ranges[[1]]$x.range ggplot_build(obj)$layout$panel_ranges[[1]]$y.range
GegznaV

17
对于ggplot2 2.2.1.9000版 和(很可能是较新的)版本,请使用以下R代码: ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
GegznaV

3
没有办法在原始绘图调用中动态地执行此操作?
jzadra's

4
在2.2.1中,您还可以使用layer_scales(ggobj)$ y $ range $ range
Alex Holcombe

40

我正在使用ggplot2版本2,但不确定是否与以前的版本相同,假设您已将图保存在plt对象上。提取范围很容易,

# y-range
layer_scales(plt)$y$range$range

# x-range
layer_scales(plt)$x$range$range

如果是构面图,则可以使用来访问各个构面的比例layer_scales(plot, row_idx, col_idx)。例如,要访问第一行和第二列的构面,

# y-range
layer_scales(plt, 1, 2)$y$range$range

# x-range
layer_scales(plt, 1, 2)$x$range$range

2
版本3.1.0
r_alanb '18

2
注意,这为您提供了要绘制的数据范围-要获得整个轴范围,您需要允许比例扩展。此外,如果已设置限制(例如,通过ylimcoord_cartesian),则将比例扩展应用于这些限制,而不是此处给出的代码返回的限制。
希瑟·特纳

22

2018年11月更新

ggplot2 版本3.1.0开始,以下工作:

obj <- qplot(mtcars$disp, bins = 5)

# x range
ggplot_build(obj)$layout$panel_params[[1]]$x.range

# y range
ggplot_build(obj)$layout$panel_params[[1]]$y.range

便利功能:

get_plot_limits <- function(plot) {
    gb = ggplot_build(plot)
    xmin = gb$layout$panel_params[[1]]$x.range[1]
    xmax = gb$layout$panel_params[[1]]$x.range[2]
    ymin = gb$layout$panel_params[[1]]$y.range[1]
    ymax = gb$layout$panel_params[[1]]$y.range[2]
    list(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax)
}
get_plot_limits(p)

直到下一次更新...


1
建议您使用便捷功能进行编辑,如果您不喜欢它,请回滚。;-)
PatrickT

1
@PatrickT您的更新真的很方便。我真的很感激:)
GegznaV

20

用得到yrange

ggplot_build(myPlot)$panel$ranges[[1]]$y.range 

和xrange与

ggplot_build(myPlot)$panel$ranges[[1]]$x.range

2
这些解决方案适用于连续的数字轴,但是如何处理带有日期(连续刻度)或分类值的轴呢?当我使用此方法时,我得到了较大的数值,这些数值需要一些转换为日期格式才能使用geom_text添加文本。
Joseph Kreke

如果我未设置轴限制,但默认情况下使用ggplot建议怎么办?我的用例是我喜欢图1的默认值,但我希望图2具有与图1相同的轴限制
。– NewNameStat

16

版本2.2.0中,必须按以下步骤进行操作:

# y-range
ggplot_build(plot.object)$layout$panel_ranges[[1]]$y.range
# x-range
ggplot_build(plot.object)$layout$panel_ranges[[1]]$x.range

8

截至2018年8月,您可以使用以下内容提取x和y轴范围。

ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range


2

如此处所述:https : //gist.github.com/tomhopper/9076152#gistcomment-2624958两种选择之间有区别:

#get ranges of the data
ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range 
ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range

#get ranges of the plot axis
ggplot_build(obj)$layout$panel_params[[1]]$x.range
ggplot_build(obj)$layout$panel_params[[1]]$y.range

这是一组便利功能,用于绘制图表列表,提取公共y轴范围并替换它。我需要它是因为我在通过ggarange以下方式排列的一个图中使用了不同的数据集:

require(ggplot2)
#get the visible scales from single plots
get_plot_view_ylimits <- function(plot) {
  gb = ggplot_build(plot)
  ymin = gb$layout$panel_params[[1]]$y.range[1]
  ymax = gb$layout$panel_params[[1]]$y.range[2]
  message(paste("limits are:",ymin,ymax))
  list(ymin = ymin, ymax = ymax)
}

#change the limit of single plot, using list of limits
change_plot_ylimits <- function(plot, nlimits){
  p <- plot + ggplot2:::limits(unlist(nlimits, use.names =FALSE),"y")
}

#adjust the scales of multiple plots
#take a list of plots, passes back adjusted list of plots
adjust_plots_shared_ylimits <- function(plotList) {
  #read limits
  first <- TRUE
  for (plot in plotList) {
    if (first) {
      nlimits <- get_plot_view_ylimits(plot)
      first <- FALSE
    } else {
      altLimits <- get_plot_view_ylimits(plot)
      nlimits$ymin <- min(nlimits$ymin,altLimits$ymin)
      nlimits$ymax <- max(nlimits$ymax,altLimits$ymax)
    }
  }
  message(paste("new limits are:",nlimits$ymin,nlimits$ymax))
  #adjust limits
  lapply(plotList,change_plot_ylimits,nlimits)
}

我认为这对其他人也可能有用。


有一个问题,也许有人知道如何处理:报告的范围“足够大”,可以将列表中所有图的范围包括在内,但它们比实际最大值大很多(例如,在列表中使用stat_smooth( method = "lm")
弗雷德里克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.