¿Cómo puedo extraer los rangos de los ejes de trazado para un objeto ggplot2?

88

Tengo un objeto de ggplot2, digamos myPlot, ¿cómo puedo identificar los rangos para los ejes xey?

No parece ser un simple múltiplo del rango de los valores de los datos, porque uno puede cambiar la escala de los gráficos, modificar los rangos de los ejes, etc. findFn(de sos) y Google no parecen estar generando resultados relevantes, aparte de cómo establecer los rangos de los ejes.

Iterador
fuente
1
Estoy bastante seguro de que no se puede extraer directamente del objeto de trazado en sí, pero puede inferirlo (en casos simples) a partir de sus datos y los valores predeterminados de expand. Vea aquí .
joran
1
Me refería al expandargumento de las scale_*funciones en ggplot. Por ejemplo, consulte los valores predeterminados que se enumeran aquí .
joran
6
Podrás extraerlo en la próxima versión ...
hadley
1
¿Podría aceptar la respuesta de Alex Holcombe en su lugar? Paul Hiemstra solo es relevante para versiones de ggplot2 de hace más de tres años.
Max Ghenis
4
** A partir de agosto de 2018, extrae los rangos de los ejes xey con lo siguiente. ** ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
Michael

Respuestas:

41

En las versiones más recientes de ggplot2, puede encontrar esta información entre la salida de ggplot_build(p), donde pestá su objeto ggplot.

Para versiones anteriores de ggplot (<0.8.9), la siguiente solución funciona:

Y hasta que Hadley lance la nueva versión, esto podría ser útil. Si no establece los límites en el gráfico, no habrá información en el objeto ggplot. Sin embargo, en ese caso, puede usar los valores predeterminados de ggplot2 y obtener el xlim y el ylim de los datos.

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

$x
NULL

$y
NULL

Una vez que establezca los límites, estarán disponibles en el objeto:

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

$y
NULL
Paul Hiemstra
fuente
34
Específicamente, en las versiones más recientes de ggplot2, puede obtener el rango y con ggplot_build (ggobj) $ panel $ rangos [[1]] $ y.range y el rango x con ggplot_build (ggobj) $ panel $ rangos [[1]] $ x.range
Alex Holcombe
11
Para la ggplot2versión 2.1.0.9001 use este Rcódigo: ggplot_build(obj)$layout$panel_ranges[[1]]$x.range ggplot_build(obj)$layout$panel_ranges[[1]]$y.range
GegznaV
18
Para la ggplot2 versión 2.2.1.9000 y (muy probablemente) más reciente, use este Rcódigo: ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
GegznaV
3
¿No hay forma de hacerlo dinámicamente dentro de la llamada de trama original?
jzadra
4
En 2.2.1 también puede usar layer_scales (ggobj) $ y $ range $ range
Alex Holcombe
40

Estoy usando la ggplot2versión 2, no estoy seguro de si esta es la misma que la versión anterior, suponga que ha guardado su gráfico en el pltobjeto. Es fácil extraer los rangos,

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

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

En el caso de un gráfico de facetas, puede acceder a escalas de facetas individuales utilizando layer_scales(plot, row_idx, col_idx). Por ejemplo, para acceder a la faceta en la primera fila y la segunda columna,

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

# x-range
layer_scales(plt, 1, 2)$x$range$range
ElRimalaya
fuente
2
Y versión 3.1.0
r_alanb
2
Tenga en cuenta que esto le da el rango de los datos que se trazarán; para obtener el rango completo del eje, deberá permitir la expansión de la escala. Además, si se han establecido límites (por ejemplo, mediante ylimocoord_cartesian ), la expansión de escala se aplicará a estos límites en lugar de a los devueltos por el código que se proporciona aquí.
Heather Turner
22

ACTUALIZACIÓN de noviembre de 2018

A partir de la ggplot2 versión 3.1.0 , funciona lo siguiente:

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

Una función de conveniencia:

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)

Hasta la próxima actualización ...

GegznaV
fuente
1
Se sugirió una edición con una función de conveniencia, retroceda si no le gusta. ;-)
PatrickT
1
@PatrickT tu actualización es realmente conveniente. Realmente lo aprecio :)
GegznaV
20

Consigue el yrange con

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

y el xrange con

ggplot_build(myPlot)$panel$ranges[[1]]$x.range
Alex Holcombe
fuente
2
Estas soluciones funcionan bien para ejes numéricos continuos, pero ¿cómo se pueden manejar ejes con fechas (escala continua) o valores categóricos? Cuando utilizo este método, obtengo valores numéricos grandes que requieren alguna conversión al formato de fecha para agregar texto usando geom_text.
Joseph Kreke
¿Qué sucede si no estoy estableciendo los límites del eje, pero uso lo que sugiere ggplot de forma predeterminada? Mi caso de uso es que me gustan los valores predeterminados para el gráfico 1, pero quiero que el gráfico 2 tenga los mismos límites de eje que el gráfico 1.
NewNameStat
16

En la versión 2.2.0, esto debe hacerse de la siguiente manera:

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

A partir de agosto de 2018, extrae los rangos de los ejes xey con lo siguiente.

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

Miguel
fuente
2

Como se menciona aquí: https://gist.github.com/tomhopper/9076152#gistcomment-2624958 hay una diferencia entre las dos opciones:

#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

Aquí hay un conjunto de funciones de conveniencia para tomar una lista de gráficos, extraer el rango común del eje y y reemplazarlo. Lo necesitaba porque utilicé diferentes conjuntos de datos dentro de un gráfico organizado a través de 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)
}

Pensé que esto también podría ser útil para otros.

Frederik
fuente
Hay un problema, tal vez alguien sepa cómo solucionarlo: los rangos informados son "lo suficientemente grandes" para incluir todos los rangos de los gráficos en la lista, pero son mucho más grandes que el máximo real (por ejemplo, en una lista de parcelas usandostat_smooth( method = "lm")
Frederik