ฉันจะแยกช่วงของแกนพล็อตสำหรับออบเจ็กต์ ggplot2 ได้อย่างไร


90

ฉันมีวัตถุจากggplot2พูดmyPlotว่าฉันจะระบุช่วงของแกน x และ y ได้อย่างไร

ดูเหมือนว่าจะไม่ใช่ช่วงของค่าข้อมูลแบบพหุคูณอย่างง่าย ๆ เพราะเราสามารถปรับขนาดพล็อตแก้ไขช่วงแกนและอื่น ๆ ได้ findFn(จากsos) และ Google ดูเหมือนจะไม่แสดงผลลัพธ์ที่เกี่ยวข้องนอกเหนือจากวิธีตั้งค่าช่วงของแกน


1
ผมค่อนข้างแน่ใจว่าไม่สามารถสกัดโดยตรงจากวัตถุที่พล็อตของตัวเอง แต่คุณสามารถอนุมานมัน (ในกรณีที่เรียบง่าย) expandจากข้อมูลและค่าเริ่มต้นสำหรับคุณ ดูที่นี่ .
joran

1
ฉันอ้างถึงexpandอาร์กิวเมนต์ของscale_*ฟังก์ชันในggplot. ตัวอย่างเช่นดูค่าเริ่มต้นที่ระบุไว้ที่นี่
joran

6
คุณจะสามารถแยกออกได้ในเวอร์ชันถัดไป ...
hadley

1
คุณช่วยยอมรับคำตอบของ Alex Holcombe แทนได้ไหม Paul Hiemstra นั้นเกี่ยวข้องกับ ggplot2 เวอร์ชันเมื่อสามปีที่แล้วเท่านั้น
Max Ghenis

4
** ณ เดือนสิงหาคม 2018 คุณแยกช่วงของแกน x และ y ดังต่อไปนี้ ** ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
Michael

คำตอบ:


41

ใน ggplot2 เวอร์ชันใหม่กว่าคุณสามารถค้นหาข้อมูลนี้ได้จากผลลัพธ์ของอ็อบเจ็กต์ ggplot ของคุณอยู่ggplot_build(p)ที่ไหนp

สำหรับ ggplot เวอร์ชันเก่า (<0.8.9) วิธีแก้ปัญหาต่อไปนี้ใช้ได้:

และจนกว่า Hadley จะออกเวอร์ชันใหม่สิ่งนี้อาจเป็นประโยชน์ หากคุณไม่กำหนดขีด จำกัด ในพล็อตจะไม่มีข้อมูลในวัตถุ ggplot อย่างไรก็ตามในกรณีนี้คุณสามารถใช้ค่าเริ่มต้นของ ggplot2 และรับ xlim และ ylim จากข้อมูล

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

$x
NULL

$y
NULL

เมื่อคุณกำหนดขีด จำกัด แล้วจะพร้อมใช้งานในออบเจ็กต์:

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

$y
NULL

34
โดยเฉพาะอย่างยิ่งใน ggplot2 เวอร์ชันที่ใหม่กว่าคุณสามารถรับ yrange ได้ด้วย ggplot_build (ggobj) $ panel $ range [[1]] $ y.range และ xrange ที่มี ggplot_build (ggobj) $ panel $ range [[1]] $ x.range
Alex Holcombe

11
สำหรับggplot2เวอร์ชัน 2.1.0.9001 ให้ใช้Rรหัสนี้: ggplot_build(obj)$layout$panel_ranges[[1]]$x.range ggplot_build(obj)$layout$panel_ranges[[1]]$y.range
GegznaV

19
สำหรับggplot2 เวอร์ชัน 2.2.1.9000 และ (ส่วนใหญ่อาจ) ใหม่กว่าให้ใช้Rรหัสนี้: ggplot_build(obj)$layout$panel_scales_x[[1]]$range$range ggplot_build(obj)$layout$panel_scales_y[[1]]$range$range
GegznaV

3
ไม่มีวิธีดำเนินการแบบไดนามิกภายในการเรียกพล็อตดั้งเดิมหรือไม่?
jzadra

4
ใน 2.2.1 คุณยังสามารถใช้ layer_scales (ggobj) $ y $ range $ range ได้
Alex Holcombe

41

ฉันใช้ggplot2เวอร์ชัน 2 ฉันไม่แน่ใจว่านี่เป็นเวอร์ชันก่อนหน้าหรือไม่สมมติว่าคุณได้บันทึกพล็อตของคุณในpltวัตถุ ง่ายต่อการแยกช่วง

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

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

layer_scales(plot, row_idx, col_idx)ในกรณีที่มีพล็อตในแง่นี้คุณสามารถเข้าถึงเครื่องชั่งน้ำหนักของแง่มุมของแต่ละบุคคลโดยใช้ ตัวอย่างเช่นในการเข้าถึง facet ในแถวแรกและคอลัมน์ที่สอง

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

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

2
และเวอร์ชัน 3.1.0
r_alanb

2
โปรดทราบว่านี่จะให้ช่วงของข้อมูลที่จะพล็อต - เพื่อให้ได้ช่วงแกนเต็มคุณจะต้องอนุญาตให้ขยายขนาดได้ ยิ่งไปกว่านั้นหากมีการกำหนดขีด จำกัด (เช่นผ่านylimหรือcoord_cartesian) การขยายมาตราส่วนจะถูกนำไปใช้กับขีด จำกัด เหล่านี้แทนที่จะส่งคืนโดยรหัสที่ระบุ
Heather Turner

22

อัพเดทพฤศจิกายน 2561

สำหรับggplot2 เวอร์ชัน 3.1.0การทำงานดังต่อไปนี้:

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

ฟังก์ชั่นอำนวยความสะดวก:

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)

จนกว่าจะมีการปรับปรุงครั้งต่อไป ...


1
แนะนำให้แก้ไขด้วยฟังก์ชั่นอำนวยความสะดวกย้อนกลับหากคุณไม่ชอบ ;-)
PatrickT

1
@PatrickT การอัปเดตของคุณสะดวกมาก ฉันซาบซึ้งจริงๆ :)
GegznaV

20

รับ yrange ด้วย

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

และ xrange ด้วย

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

2
โซลูชันเหล่านี้ทำงานได้ดีสำหรับแกนตัวเลขที่ต่อเนื่อง แต่หนึ่งจะจัดการกับแกนที่มีวันที่ (มาตราส่วนต่อเนื่อง) หรือค่าหมวด เมื่อฉันใช้วิธีนี้ฉันได้รับค่าตัวเลขจำนวนมากที่ต้องมีการแปลงเป็นรูปแบบวันที่เพื่อเพิ่มข้อความโดยใช้ geom_text
Joseph Kreke

จะเกิดอะไรขึ้นถ้าฉันไม่ได้ตั้งค่าขีด จำกัด แกน แต่ใช้สิ่งที่ ggplot แนะนำโดยค่าเริ่มต้น กรณีการใช้งานของฉันคือฉันชอบค่าเริ่มต้นสำหรับพล็อต 1 แต่ฉันต้องการให้พล็อต 2 มีขีด จำกัด แกนเดียวกันกับพล็อต 1
NewNameStat

16

ในเวอร์ชัน 2.2.0จะต้องดำเนินการดังนี้:

# 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

ณ เดือนสิงหาคม 2018 คุณแยกช่วง x และแกน y ออกมาดังต่อไปนี้

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


3

ดังที่กล่าวไว้ที่นี่: https://gist.github.com/tomhopper/9076152#gistcomment-2624958มีความแตกต่างระหว่างสองตัวเลือก:

#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 ทั่วไปและแทนที่ ฉันต้องการมันเพราะฉันใช้ชุดข้อมูลที่แตกต่างกันภายในกราฟเดียวที่จัดเรียงผ่าน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)
}

ฉันคิดว่านี่อาจเป็นประโยชน์สำหรับคนอื่น ๆ


มีปัญหาอย่างหนึ่งที่อาจมีคนรู้วิธีจัดการ: ช่วงที่รายงานนั้น "ใหญ่พอ" ที่จะรวมช่วงทั้งหมดจากพล็อตในรายการ แต่มีขนาดใหญ่กว่าค่าสูงสุดที่แท้จริงมาก (เช่นในรายการ แปลงโดยใช้stat_smooth( method = "lm")
Frederik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.