Bagaimana cara mengekstrak rentang sumbu plot untuk objek ggplot2?

90

Saya memiliki sebuah objek dari ggplot2, katakanlah myPlot, bagaimana saya bisa mengidentifikasi rentang untuk sumbu x dan y?

Tampaknya ini bukan kelipatan sederhana dari rentang nilai data, karena seseorang dapat mengubah skala plot, mengubah rentang sumbu, dan seterusnya. findFn(dari sos) dan Google tampaknya tidak memberikan hasil yang relevan, selain cara mengatur rentang sumbu.

Iterator
sumber
1
Saya cukup yakin itu tidak dapat diekstraksi langsung dari objek plot itu sendiri, tetapi Anda dapat menyimpulkannya (dalam kasus sederhana) dari data Anda dan nilai default untuk expand. Lihat disini .
joran
1
Saya mengacu pada expandargumen scale_*fungsi di ggplot. Misalnya, lihat default yang tercantum di sini .
joran
6
Anda akan dapat mengekstraknya di versi berikutnya ...
hadley
1
Bisakah Anda menerima jawaban Alex Holcombe saja? Paul Hiemstra hanya relevan untuk versi ggplot2 lebih dari tiga tahun lalu.
Max Ghenis
4
** Mulai Agustus 2018, Anda mengekstrak rentang sumbu x dan y dengan berikut ini. ** ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
Michael

Jawaban:

41

Di versi ggplot2 yang lebih baru, Anda dapat menemukan informasi ini di antara keluaran ggplot_build(p), di mana pobjek ggplot Anda.

Untuk versi ggplot (<0.8.9) yang lebih lama, solusi berikut berfungsi:

Dan hingga Hadley merilis versi baru, ini mungkin bisa membantu. Jika Anda tidak mengatur batasan di plot, tidak akan ada info di objek ggplot. Namun, dalam hal ini Anda dapat menggunakan default ggplot2 dan mendapatkan xlim dan ylim dari data.

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

$x
NULL

$y
NULL

Setelah Anda menetapkan batasan, batasan tersebut menjadi tersedia di objek:

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

$y
NULL
Paul Hiemstra
sumber
34
Secara khusus, dalam versi ggplot2 yang lebih baru, Anda bisa mendapatkan yrange dengan ggplot_build (ggobj) $ panel $ range [[1]] $ y.range dan xrange dengan ggplot_build (ggobj) $ panel $ range [[1]] $ x.range
Alex Holcombe
11
Untuk ggplot2versi 2.1.0.9001 gunakan Rkode ini : ggplot_build(obj)$layout$panel_ranges[[1]]$x.range ggplot_build(obj)$layout$panel_ranges[[1]]$y.range
GegznaV
19
Untuk ggplot2 versi 2.2.1.9000 dan (kemungkinan besar) yang lebih baru, gunakan Rkode ini : ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
GegznaV
3
Apakah tidak ada cara untuk melakukannya secara dinamis dalam panggilan plot asli?
jzadra
4
Di 2.2.1 Anda juga dapat menggunakan layer_scales (ggobj) $ y $ range $ range
Alex Holcombe
41

Saya menggunakan ggplot2versi 2, saya tidak yakin apakah ini sama dengan versi sebelumnya, Misalkan Anda telah menyimpan plot Anda pada pltobjek. Mudah untuk mengekstrak rentangnya,

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

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

Dalam kasus plot faset, Anda dapat mengakses skala faset individu menggunakan layer_scales(plot, row_idx, col_idx). Misalnya untuk mengakses facet pada baris pertama dan kolom kedua,

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

# x-range
layer_scales(plt, 1, 2)$x$range$range
TheRimalaya
sumber
2
Dan versi 3.1.0
r_alanb
2
Perhatikan ini memberi Anda rentang data yang akan diplot - untuk mendapatkan rentang sumbu penuh Anda perlu mengizinkan perluasan skala. Selain itu, jika batas telah ditetapkan (misalnya melalui ylimatau coord_cartesian) perluasan skala akan diterapkan ke batas ini daripada yang dikembalikan oleh kode yang diberikan di sini.
Heather Turner
22

UPDATE November 2018

Pada ggplot2 versi 3.1.0 , berikut ini berfungsi:

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

Fungsi kenyamanan:

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)

Sampai pembaruan berikutnya ...

GegznaV
sumber
1
Menyarankan pengeditan dengan fungsi kenyamanan, kembalikan jika Anda tidak menyukainya. ;-)
PatrickT
1
@PatrickT pembaruan Anda benar-benar nyaman. Saya sangat menghargainya :)
GegznaV
20

Dapatkan tahun dengan

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

dan xrange dengan

ggplot_build(myPlot)$panel$ranges[[1]]$x.range
Alex Holcombe
sumber
2
Solusi ini bekerja dengan baik untuk sumbu numerik kontinu, tetapi bagaimana cara menangani sumbu dengan tanggal (skala kontinu) atau nilai kategori? Ketika saya menggunakan metode ini, saya mendapatkan nilai numerik besar yang memerlukan beberapa konversi ke format tanggal untuk menambahkan teks menggunakan geom_text.
Joseph Kreke
Bagaimana jika saya tidak mengatur batas sumbu tetapi menggunakan apa yang disarankan ggplot secara default? Kasus penggunaan saya adalah saya menyukai nilai default untuk plot 1 tetapi saya ingin plot 2 memiliki batas sumbu yang sama seperti plot 1.
NewNameStat
16

Dalam versi 2.2.0 ini harus dilakukan sebagai berikut:

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

Mulai Agustus 2018 Anda mengekstrak rentang sumbu x dan y dengan berikut ini.

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

Michael
sumber
3

Seperti yang disebutkan di sini: https://gist.github.com/tomhopper/9076152#gistcomment-2624958 ada perbedaan antara kedua opsi tersebut:

#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

Berikut adalah seperangkat fungsi praktis untuk mengambil daftar plot, mengekstrak rentang sumbu y umum dan menggantinya. Saya membutuhkannya karena saya menggunakan kumpulan data yang berbeda dalam satu grafik yang diatur melalui 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)
}

Saya pikir ini mungkin juga berguna untuk orang lain.

Frederik
sumber
Ada satu masalah, mungkin seseorang tahu bagaimana mengatasinya: Rentang yang dilaporkan "cukup besar" untuk menyertakan semua rentang dari plot dalam daftar, tetapi rentang tersebut jauh lebih besar dari maksimum sebenarnya (misalnya, dalam daftar plot menggunakanstat_smooth( method = "lm")
Frederik