Wie kann ich die Bereiche der Plotachsen für ein ggplot2-Objekt extrahieren?

87

Ich habe ein Objekt von beispielsweise ggplot2, myPlotwie kann ich die Bereiche für die x- und y-Achse identifizieren?

Es scheint kein einfaches Vielfaches des Datenwertbereichs zu sein, da Diagramme neu skaliert, Achsenbereiche geändert werden können usw. findFn(von sos) und Google scheinen keine relevanten Ergebnisse zu liefern, außer wie die Achsenbereiche eingestellt werden.

Iterator
quelle
1
Ich bin mir ziemlich sicher, dass dies nicht direkt aus dem Plotobjekt selbst extrahiert werden kann, aber Sie können es (in einfachen Fällen) aus Ihren Daten und den Standardwerten für ableiten expand. Siehe hier .
Joran
1
Ich bezog mich auf das expandArgument zu den scale_*Funktionen in ggplot. Siehe zum Beispiel die hier aufgeführten Standardeinstellungen .
Joran
6
Sie können es in der nächsten Version extrahieren ...
Hadley
1
Könnten Sie bitte stattdessen die Antwort von Alex Holcombe akzeptieren? Paul Hiemstra ist nur für Versionen von ggplot2 von vor über drei Jahren relevant.
Max Ghenis
3
** Ab August 2018 extrahieren Sie die x- und y-Achsenbereiche wie folgt. ** ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
Michael

Antworten:

41

In neueren Versionen von ggplot2 finden Sie diese Informationen in der Ausgabe von ggplot_build(p), wo psich Ihr ggplot-Objekt befindet.

Für ältere Versionen von ggplot (<0.8.9) funktioniert die folgende Lösung:

Und bis Hadley die neue Version veröffentlicht, könnte dies hilfreich sein. Wenn Sie die Grenzen im Plot nicht festlegen, enthält das ggplot-Objekt keine Informationen. In diesem Fall können Sie jedoch die Standardeinstellungen von ggplot2 verwenden und xlim und ylim aus den Daten abrufen.

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

$x
NULL

$y
NULL

Sobald Sie die Grenzwerte festgelegt haben, werden sie im Objekt verfügbar:

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

$y
NULL
Paul Hiemstra
quelle
34
Insbesondere in den neueren Versionen von ggplot2 können Sie den Bereich mit ggplot_build (ggobj) $ panel $ Bereiche [[1]] $ y.range und den Bereich mit ggplot_build (ggobj) $ panel $ Bereiche [[1]] $ abrufen x.range
Alex Holcombe
11
Für ggplot2Version 2.1.0.9001 verwenden Sie diesen RCode: ggplot_build(obj)$layout$panel_ranges[[1]]$x.range ggplot_build(obj)$layout$panel_ranges[[1]]$y.range
GegznaV
17
Für ggplot2 Version 2.2.1.9000 und (höchstwahrscheinlich) neuere verwenden Sie diesen RCode: ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
GegznaV
3
Gibt es keine Möglichkeit, dies innerhalb des ursprünglichen Plotaufrufs dynamisch zu tun?
Jzadra
4
In 2.2.1 können Sie auch layer_scales (ggobj) $ y $ range $ range verwenden
Alex Holcombe
39

Ich verwende ggplot2Version 2 und bin mir nicht sicher, ob dies mit der vorherigen Version identisch ist. Angenommen, Sie haben Ihr Diagramm auf einem pltObjekt gespeichert . Es ist einfach, die Bereiche zu extrahieren,

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

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

Im Falle eines Facettendiagramms können Sie mit auf Skalen einzelner Facetten zugreifen layer_scales(plot, row_idx, col_idx). Um beispielsweise auf die Facette in der ersten Zeile und zweiten Spalte zuzugreifen,

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

# x-range
layer_scales(plt, 1, 2)$x$range$range
TheRimalaya
quelle
2
Und Version 3.1.0
r_alanb
2
Beachten Sie, dass Sie damit den Bereich der zu zeichnenden Daten erhalten. Um den vollen Achsenbereich zu erhalten, müssen Sie die Skalenerweiterung berücksichtigen. Wenn Grenzwerte festgelegt wurden (z. B. über ylimoder coord_cartesian), wird die Skalenerweiterung auf diese Grenzwerte angewendet und nicht auf diejenigen, die durch den hier angegebenen Code zurückgegeben werden.
Heather Turner
22

November 2018 UPDATE

Ab ggplot2 Version 3.1.0 funktioniert Folgendes:

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

Eine Komfortfunktion:

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)

Bis zum nächsten Update ...

GegznaV
quelle
1
Vorgeschlagene Bearbeitung mit einer praktischen Funktion, Rollback, wenn es Ihnen nicht gefällt. ;-)
PatrickT
1
@PatrickT Ihr Update ist wirklich praktisch. Ich weiß es wirklich zu schätzen :)
GegznaV
20

Holen Sie sich die yrange mit

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

und der xrange mit

ggplot_build(myPlot)$panel$ranges[[1]]$x.range
Alex Holcombe
quelle
2
Diese Lösungen eignen sich gut für fortlaufende numerische Achsen. Wie kann man jedoch mit Achsen mit Datumsangaben (fortlaufende Skala) oder kategorialen Werten umgehen? Wenn ich diese Methode verwende, erhalte ich große numerische Werte, die eine Konvertierung in das Datumsformat erfordern, um Text mit geom_text hinzuzufügen.
Joseph Kreke
Was ist, wenn ich nicht die Achsengrenzen einstelle, sondern standardmäßig das verwende, was ggplot vorschlägt? Mein Anwendungsfall ist, dass ich die Standardwerte für Plot 1 mag, aber ich möchte, dass Plot 2 die gleichen
Achsengrenzen
16

In Version 2.2.0 muss dies wie folgt erfolgen:

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

Ab August 2018 extrahieren Sie die x- und y-Achsenbereiche wie folgt.

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

Michael
quelle
2

Wie hier erwähnt: https://gist.github.com/tomhopper/9076152#gistcomment-2624958 gibt es einen Unterschied zwischen den beiden Optionen:

#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

Hier finden Sie eine Reihe von praktischen Funktionen, mit denen Sie eine Liste von Plots erstellen, den gemeinsamen Bereich der y-Achse extrahieren und ersetzen können. Ich brauchte es, weil ich verschiedene Datensätze in einem Diagramm verwendet habe, das über Folgendes angeordnet ist 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)
}

Ich dachte, das könnte auch für andere nützlich sein.

Frederik
quelle
Es gibt ein Problem, vielleicht weiß jemand, wie man damit umgeht: Die gemeldeten Bereiche sind "groß genug", um alle Bereiche aus den Plots in die Liste aufzunehmen, aber sie sind viel größer als das tatsächliche Maximum (z. B. in einer Liste von Handlungen mitstat_smooth( method = "lm")
Frederik