Làm cách nào để trích xuất phạm vi trục biểu đồ cho đối tượng ggplot2?


88

Tôi có một đối tượng ggplot2, chẳng hạn myPlot, làm cách nào tôi có thể xác định phạm vi cho trục x và y?

Nó dường như không phải là bội số đơn giản của phạm vi giá trị dữ liệu, bởi vì người ta có thể bán lại các ô, sửa đổi phạm vi trục, v.v. findFn(từ sos) và Google dường như không hiển thị các kết quả có liên quan, ngoài cách thiết lập phạm vi của trục.


1
Tôi khá chắc rằng điều đó không thể được trích xuất trực tiếp từ chính đối tượng âm mưu, nhưng bạn có thể suy ra nó (trong các trường hợp đơn giản) từ dữ liệu của bạn và các giá trị mặc định cho expand. Xem tại đây .
joran

1
Tôi đã đề cập đến expandđối số cho các scale_*hàm trong ggplot. Ví dụ, xem các giá trị mặc định được liệt kê ở đây .
joran

6
Bạn sẽ có thể giải nén nó trong phiên bản tiếp theo ...
hadley

1
Thay vào đó, bạn có thể vui lòng chấp nhận câu trả lời của Alex Holcombe không? Của Paul Hiemstra chỉ phù hợp với các phiên bản của ggplot2 từ hơn ba năm trước.
Max Ghenis

4
** Kể từ tháng 8 năm 2018, bạn trích xuất phạm vi trục x và y với những điều sau. ** ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
Michael

Câu trả lời:


41

Trong các phiên bản mới hơn của ggplot2, bạn có thể tìm thấy thông tin này trong đầu ra của ggplot_build(p), nơi plà đối tượng ggplot của bạn.

Đối với các phiên bản cũ hơn của ggplot (<0,8,9), giải pháp sau hoạt động:

Và cho đến khi Hadley phát hành phiên bản mới, điều này có thể hữu ích. Nếu bạn không đặt giới hạn trong cốt truyện, sẽ không có thông tin trong đối tượng ggplot. Tuy nhiên, trong trường hợp đó, bạn có thể sử dụng giá trị mặc định của ggplot2 và lấy xlim và ylim từ dữ liệu.

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

$x
NULL

$y
NULL

Sau khi bạn đặt giới hạn, chúng sẽ có sẵn trong đối tượng:

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

$y
NULL

34
Cụ thể, trong các phiên bản mới hơn của ggplot2, bạn có thể tải yrange với ggplot_build (ggobj) $ panel $ range [[1]] $ y.range và xrange với ggplot_build (ggobj) $ panel $ range [[1]] $ x.range
Alex Holcombe

11
Đối với ggplot2phiên bản 2.1.0.9001, hãy sử dụng Rmã này : ggplot_build(obj)$layout$panel_ranges[[1]]$x.range ggplot_build(obj)$layout$panel_ranges[[1]]$y.range
GegznaV 28/10/16

18
Đối với ggplot2 phiên bản 2.2.1.9000 và (có lẽ hầu hết) sử dụng mới này Rmã: ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
GegznaV

3
Không có cách nào để làm điều đó một cách linh hoạt trong lệnh gọi cốt truyện ban đầu?
jzadra

4
Trong 2.2.1, bạn cũng có thể sử dụng layer_scales (ggobj) $ y $ range $ range
Alex Holcombe

40

Tôi đang sử dụng ggplot2phiên bản 2, tôi không chắc cái này có giống với phiên bản trước hay không, Giả sử bạn đã lưu âm mưu của mình trên pltđối tượng. Thật dễ dàng để trích xuất các phạm vi,

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

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

Trong trường hợp biểu đồ khía cạnh, bạn có thể truy cập thang đo của từng khía cạnh bằng cách sử dụng layer_scales(plot, row_idx, col_idx). Ví dụ: để truy cập khía cạnh ở hàng đầu tiên và cột thứ hai,

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

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

2
phiên bản 3.1.0
r_alanb 17/12/18

2
Lưu ý rằng điều này cung cấp cho bạn phạm vi dữ liệu được vẽ - để có được phạm vi trục đầy đủ, bạn sẽ cần cho phép mở rộng tỷ lệ. Hơn nữa, nếu các giới hạn đã được đặt (ví dụ: thông qua ylimhoặc coord_cartesian) thì việc mở rộng quy mô sẽ được áp dụng cho các giới hạn này thay vì các giới hạn được trả về bởi mã được đưa ra ở đây.
Heather Turner

22

CẬP NHẬT THÁNG 11/2018

Kể từ ggplot2 phiên bản 3.1.0 , các tính năng sau hoạt động:

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

Một chức năng tiện lợi:

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)

Cho đến bản cập nhật tiếp theo ...


1
Đề xuất chỉnh sửa với chức năng tiện lợi, quay lại nếu bạn không thích. ;-)
PatrickT

1
@PatrickT cập nhật của bạn thực sự thuận tiện. Tôi thực sự đánh giá cao nó :)
GegznaV

20

Nhận yrange với

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

và xrange với

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

2
Các giải pháp này hoạt động tốt cho các trục số liên tục, nhưng làm thế nào một người có thể xử lý các trục có ngày tháng (tỷ lệ liên tục) hoặc các giá trị phân loại? Khi tôi sử dụng phương pháp này, tôi nhận được các giá trị số lớn yêu cầu một số chuyển đổi sang định dạng ngày tháng để thêm văn bản bằng cách sử dụng geom_text.
Joseph Kreke

Điều gì sẽ xảy ra nếu tôi không đặt giới hạn trục mà sử dụng những gì ggplot đề xuất theo mặc định? Trường hợp sử dụng của tôi là tôi thích các giá trị mặc định cho cốt truyện 1 nhưng tôi muốn âm mưu 2 để có các giới hạn trục giống như cốt truyện 1.
NewNameStat

16

Trong phiên bản 2.2.0, điều này phải được thực hiện như sau:

# 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

Kể từ tháng 8 năm 2018, bạn trích xuất phạm vi trục x và y với những điều sau.

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


2

Như đã đề cập ở đây: https://gist.github.com/tomhopper/9076152#gistcomment-2624958 có sự khác biệt giữa hai tùy chọn:

#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 là một tập hợp các hàm tiện lợi để lấy danh sách các ô, trích xuất dải trục y phổ biến và thay thế nó. Tôi cần nó vì tôi đã sử dụng các tập dữ liệu khác nhau trong một biểu đồ được sắp xếp qua 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)
}

Tôi nghĩ điều này cũng có thể hữu ích cho những người khác.


Có một vấn đề, có lẽ ai đó biết cách giải quyết: Các phạm vi được báo cáo là "đủ lớn" để bao gồm tất cả các phạm vi từ các ô trong danh sách, nhưng chúng lớn hơn rất nhiều so với mức tối đa thực tế (giả sử trong danh sách sử dụng âm mưustat_smooth( method = "lm")
Frederik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.