R, как установить несколько графиков bar_chart, чтобы иметь такую ​​же ширину через grid.arrange? [Дубликат]

Пожалуйста, посмотрите на эту библиотеку Typewriter

Он скрывает не только классы, перечисления, интерфейсы и т. д., но также и api-контроллеры, которые просто удивительны ..

плюс он делает, как только вы сохраняете исходный файл .cs, поэтому мне не нужно использовать какой-либо внешний инструмент для этого. Сохраните .cs, и вы получите обновление .ts

42
задан Uwe 14 January 2017 в 10:40
поделиться

4 ответа

Редактирование: очень легко с пакетом egg, доступным в github

# install.package(devtools)
# devtools::install_github("baptiste/egg")

library(egg)

p1 <- ggplot(data.frame(x=c("a","b","c"),
                        y=c("happy","sad","ambivalent about life")),
             aes(x=factor(0),fill=x)) + 
      geom_bar()
p2 <- ggplot(data.frame(x=c("a","b","c"),
                        y=c("happy","sad","ambivalent about life")),
             aes(x=factor(0),fill=y)) + 
      geom_bar()

ggarrange(p1,p2, ncol = 1)

Оригинал Udated to ggplot2 2.2.1

Вот решение, которое использует функции из gtable пакет, и фокусируется на ширинах полей легенды. (Более общее решение можно найти здесь здесь .)

library(ggplot2)   
library(gtable)    
library(grid)
library(gridExtra) 

# Your plots
p1 <- ggplot(data.frame(x=c("a","b","c"),y=c("happy","sad","ambivalent about life")),aes(x=factor(0),fill=x)) + geom_bar()
p2 <- ggplot(data.frame(x=c("a","b","c"),y=c("happy","sad","ambivalent about life")),aes(x=factor(0),fill=y)) + geom_bar()

# Get the gtables
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# Set the widths
gA$widths <- gB$widths

# Arrange the two charts.
# The legend boxes are centered
grid.newpage()
grid.arrange(gA, gB, nrow = 2)

Если, кроме того, поля легенды необходимо оставить обоснованными и заимствовать некоторый код из здесь , написанный @Julius

p1 <- ggplot(data.frame(x=c("a","b","c"),y=c("happy","sad","ambivalent about life")),aes(x=factor(0),fill=x)) + geom_bar()
p2 <- ggplot(data.frame(x=c("a","b","c"),y=c("happy","sad","ambivalent about life")),aes(x=factor(0),fill=y)) + geom_bar()

# Get the widths
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Set the widths
gA$widths <- gB$widths

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Arrange the two charts
grid.newpage()
grid.arrange(gA, gB, nrow = 2)

enter image description here [/g2]

Альтернативные решения Существуют функции rbind и cbind в пакете gtable для объединения grobs в один grob. Для диаграмм здесь ширины должны быть установлены с помощью size = "max", но версия CRAN gtable выдает ошибку.

Один вариант: должно быть очевидно, что легенда на втором графике шире , Поэтому используйте опцию size = "last".

# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# Combine the plots
g = rbind(gA, gB, size = "last")

# Draw it
grid.newpage()
grid.draw(g)

Левые выровненные слева:

# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Combine the plots
g = rbind(gA, gB, size = "last")

# Draw it
grid.newpage()
grid.draw(g)

Второй вариант - использовать rbind из пакета gridExtra Baptiste

# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# Combine the plots
g = gridExtra::rbind.gtable(gA, gB, size = "max")

# Draw it
grid.newpage()
grid.draw(g)

Левые легенды:

# Get the grobs
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)

# The parts that differs in width
leg1 <- convertX(sum(with(gA$grobs[[15]], grobs[[1]]$widths)), "mm")
leg2 <- convertX(sum(with(gB$grobs[[15]], grobs[[1]]$widths)), "mm")

# Add an empty column of "abs(diff(widths)) mm" width on the right of 
# legend box for gA (the smaller legend box)
gA$grobs[[15]] <- gtable_add_cols(gA$grobs[[15]], unit(abs(diff(c(leg1, leg2))), "mm"))

# Combine the plots
g = gridExtra::rbind.gtable(gA, gB, size = "max")

# Draw it
grid.newpage()
grid.draw(g)
33
ответ дан Community 20 August 2018 в 06:55
поделиться
  • 1
    Отлично! Являются ли эти функции и переменные документированными в любом месте или вы просто просматриваете источник ggplot? – jamie.f.olson 28 April 2013 в 22:46
  • 2
    @ jamie.f.olson В CRAN есть руководство gtable , но кроме этого, нужно учитывать примеры других на SO и иногда в списке рассылки ggplot . – Sandy Muspratt 29 April 2013 в 00:16
  • 3
    Вы пытались объединить графики? Это должно сработать, но я не могу вспомнить, закончили ли мы этот код. – hadley 29 April 2013 в 13:09
  • 4
    Я, кажется, сталкиваюсь с проблемой @baptiste упоминает единицы при использовании rbind – jamie.f.olson 3 May 2013 в 23:16
  • 5
    Этот метод по-прежнему является наилучшим способом выровнять поля легенды или какие-либо новые функции для этого? Кажется, что очень много ручного труда это делать очень часто. – Reilstein 23 September 2016 в 00:27

Пакет cowplot также имеет функцию align_plots для этой цели (вывод не показан),

both2 <- align_plots(p1, p2, align="hv", axis="tblr")
p1x <- ggdraw(both2[[1]])
p2x <- ggdraw(both2[[2]])
save_plot("cow1.png", p1x)
save_plot("cow2.png", p2x)

, а также plot_grid, который сохраняет графики в один и тот же файл.

library(cowplot)
both <- plot_grid(p1, p2, ncol=1, labels = c("A", "B"), align = "v")
save_plot("cow.png", both)

5
ответ дан Aaron 20 August 2018 в 06:55
поделиться

Как указывает @hadley, rbind.gtable должен иметь возможность справиться с этим,

  grid.draw(rbind(ggplotGrob(p1), ggplotGrob(p2), size="last"))

, однако в идеале ширина макета должна быть size="max", которая не справляется хорошо с некоторыми типами узлов сетки.

8
ответ дан baptiste 20 August 2018 в 06:55
поделиться
  • 1
    Это: Error in mmm < each : comparison of these types is not implemented, что вы имеете в виду? Я не видел примера сообщения об ошибке на странице проблемы. – jamie.f.olson 3 May 2013 в 23:14
  • 2
    вам нужно запустить пример кода, чтобы увидеть его – baptiste 4 May 2013 в 01:11

Просто случайно я заметил, что решение Аруна, которое он предложил в своих комментариях, не было подобрано. Я считаю, что его простой и эффективный подход действительно стоит проиллюстрировать.

Арун предложил переместить легенду сверху или снизу:

ggplot(df, aes(x=factor(0), fill=x)) + geom_bar() + theme(legend.position = "bottom")
ggplot(df, aes(x=factor(0), fill=y)) + geom_bar() + theme(legend.position = "bottom")

Теперь графики имеют ту же ширину, что и запрос. Кроме того, площадь участка одинакового размера в обоих случаях.

Если есть больше факторов или даже более длинных меток, может возникнуть необходимость играть с легендой, например, для отображения легенды в двух или более строках. theme() и guide_legend() имеют несколько параметров для управления положением и появлением легенд в ggplot2.

2
ответ дан Uwe 20 August 2018 в 06:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: