Як я можу витягти діапазони графічних осей для об'єкта ggplot2?


88

У мене є об’єкт ggplot2, скажімо myPlot, як я можу визначити діапазони осей x та y?

Це, здається, не є простим кратним діапазону значень даних, оскільки можна масштабувати графіки, змінювати діапазони осей тощо. findFn(від sos) та Google, схоже, не показують відповідних результатів, крім того, як встановити діапазони осей.


1
Я майже впевнений, що неможливо отримати безпосередньо з самого об'єкта ділянки, але ви можете зробити це (у простих випадках) зі своїх даних та значень за замовчуванням для expand. Дивіться тут .
joran

1
Я мав на увазі expandаргумент scale_*функцій у ggplot. Наприклад, див. Перелічені тут значення за замовчуванням .
joran

6
Ви зможете витягти його в наступній версії ...
hadley

1
Чи не могли б ви прийняти відповідь Алекса Холкомба? Paul Hiemstra's має значення лише для версій 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
Майкл

Відповіді:


41

У новіших версіях ggplot2 ви можете знайти цю інформацію серед вихідних даних ggplot_build(p), де pзнаходиться ваш об'єкт ggplot.

Для старих версій ggplot (<0.8.9) працює таке рішення:

І поки Хадлі не випустить нову версію, це може бути корисно. Якщо ви не встановите обмеження в графіку, інформація в об’єкті 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

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

17
Для 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

40

Я використовую 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). Наприклад, щоб отримати доступ до грані в першому рядку та другому стовпці,

# 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), розширення масштабу застосовуватиметься до цих обмежень, а не до тих, що повертаються кодом, наведеним тут.
Хізер Тернер

22

Листопад 2018 ОНОВЛЕННЯ

Станом на 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.
Джозеф Креке

Що робити, якщо я не встановлюю межі осей, а використовую те, що пропонує 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


2

Як зазначалося тут: 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")
Фредерік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.