Come posso estrarre gli intervalli degli assi del grafico per un oggetto ggplot2?


88

Ho un oggetto da ggplot2, diciamo myPlot, come posso identificare gli intervalli per gli assi x e y?

Non sembra essere un semplice multiplo dell'intervallo dei valori dei dati, perché è possibile ridimensionare i grafici, modificare gli intervalli degli assi e così via. findFn(da sos) e Google non sembrano fornire risultati pertinenti, a parte come impostare gli intervalli degli assi.


1
Sono abbastanza sicuro che non possa essere estratto direttamente dall'oggetto del grafico stesso, ma puoi dedurlo (in casi semplici) dai tuoi dati e dai valori predefiniti per expand. Vedi qui .
joran

1
Mi riferivo expandall'argomento delle scale_*funzioni in ggplot. Ad esempio, vedere le impostazioni predefinite elencate qui .
joran

6
Sarai in grado di estrarlo nella prossima versione ...
hadley

1
Potresti invece accettare la risposta di Alex Holcombe? Quello di Paul Hiemstra è rilevante solo per le versioni di ggplot2 di oltre tre anni fa.
Max Ghenis

4
** A partire da agosto 2018 si estraggono gli intervalli degli assi xey con quanto segue. ** ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
Michael

Risposte:


41

Nelle versioni più recenti di ggplot2, puoi trovare queste informazioni nell'output di ggplot_build(p), dov'è il ptuo oggetto ggplot.

Per le versioni precedenti di ggplot (<0.8.9), la seguente soluzione funziona:

E fino a quando Hadley non rilascia la nuova versione, questo potrebbe essere utile. Se non imposti i limiti nel grafico, non ci saranno informazioni nell'oggetto ggplot. Tuttavia, in questo caso puoi usare i valori predefiniti di ggplot2 e ottenere xlim e ylim dai dati.

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

$x
NULL

$y
NULL

Una volta impostati i limiti, diventano disponibili nell'oggetto:

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

$y
NULL

34
In particolare, nelle versioni più recenti di ggplot2, puoi ottenere yrange con ggplot_build (ggobj) $ panel $ range [[1]] $ y.range e xrange con ggplot_build (ggobj) $ panel $ intervalli [[1]] $ x.range
Alex Holcombe

11
Per la ggplot2versione 2.1.0.9001 utilizzare questo Rcodice: ggplot_build(obj)$layout$panel_ranges[[1]]$x.range ggplot_build(obj)$layout$panel_ranges[[1]]$y.range
GegznaV

18
Per la ggplot2 versione 2.2.1.9000 e (molto probabilmente) più recente utilizzare questo Rcodice: ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
GegznaV

3
Non c'è modo di farlo dinamicamente all'interno della trama originale?
jzadra

4
Nella 2.2.1 puoi anche usare layer_scales (ggobj) $ y $ range $ range
Alex Holcombe

40

Sto usando la ggplot2versione 2, non sono sicuro che sia la stessa versione precedente, supponiamo di aver salvato la trama pltsull'oggetto. È facile estrarre gli intervalli,

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

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

In caso di sfaccettatura, è possibile accedere alle scale delle singole sfaccettature utilizzando layer_scales(plot, row_idx, col_idx). Ad esempio, per accedere al facet nella prima riga e nella seconda colonna,

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

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

2
E la versione 3.1.0
r_alanb

2
Nota che questo ti dà l'intervallo dei dati da tracciare: per ottenere l'intervallo completo dell'asse dovrai consentire l'espansione della scala. Inoltre, se sono stati impostati dei limiti (es. Tramite ylimo coord_cartesian) l'espansione della scala verrà applicata a questi limiti anziché a quelli restituiti dal codice qui fornito.
Heather Turner

22

AGGIORNAMENTO novembre 2018

A partire dalla ggplot2 versione 3.1.0 , funziona quanto segue:

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 funzione di comodità:

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)

Fino al prossimo aggiornamento ...


1
Suggerito una modifica con una funzione di comodità, roll-back se non ti piace. ;-)
PatrickT

1
@PatrickT il tuo aggiornamento è davvero conveniente. Lo apprezzo davvero :)
GegznaV

20

Prendi la yrange con

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

e xrange con

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

2
Queste soluzioni funzionano bene per assi numerici continui, ma come si possono gestire assi con date (scala continua) o valori categoriali? Quando utilizzo questo metodo ottengo valori numerici di grandi dimensioni che richiedono una certa conversione in formato data per aggiungere testo utilizzando geom_text.
Joseph Kreke

E se non imposto i limiti degli assi ma utilizzo quello che ggplot suggerisce di default? Il mio caso d'uso è che mi piacciono i valori predefiniti per il grafico 1 ma voglio che il
grafico

16

Nella versione 2.2.0 questo deve essere fatto come segue:

# 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

A partire da agosto 2018 si estraggono gli intervalli degli assi xey con quanto segue.

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


2

Come accennato qui: https://gist.github.com/tomhopper/9076152#gistcomment-2624958 c'è una differenza tra le due opzioni:

#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

Ecco una serie di funzioni utili per prendere un elenco di grafici, estrarre l'intervallo comune dell'asse y e sostituirlo. Ne avevo bisogno perché ho utilizzato diversi set di dati all'interno di un grafico organizzato tramite 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)
}

Ho pensato che questo potrebbe essere utile anche per altri.


C'è un problema, forse qualcuno sa come affrontarlo: gli intervalli riportati sono "abbastanza grandi" da includere tutti gli intervalli dei grafici nell'elenco, ma sono molto più grandi del massimo effettivo (ad esempio, in un elenco di trame utilizzandostat_smooth( method = "lm")
Frederik
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.