Уменьшите ширину двух расположенных рядом друг с другом geom_violins, сохранив при этом размеры отдельных скрипок.

Я пытаюсь создать два расположенных рядом графика geom_violin и уменьшить левую и правую границы, а также средний разделитель между основными категориями осей x обоих графиков. Вот минимальный пример, иллюстрирующий то, чего я пытаюсь достичь:

require(dplyr)
require(ggplot2)
require(grid)
require(gridExtra)
require(cowplot)

# two major categories (cut) and five 
# subcategories (color) are enough for the purpose of this question
pi <- filter(diamonds, (cut=="Premium" | cut=="Ideal") & color<"I")
pi$cut <- factor(pi$cut)
pi$color <- factor(pi$color)

th1 <- theme_bw() + theme(legend.position = "none")

g1 <- ggplot(data=pi, aes(x=cut, fill=color, y=price)) +
  geom_violin(width=0.5) + th1

g2 <- ggplot(data=pi, aes(x=cut, fill=color, y=depth)) +
  geom_violin(width=0.5) + th1


grid.newpage()
grid.arrange(plot_grid(g1,g2, ncol = 2, rel_widths = c(0.3,0.3)))

Этот код создаст что-то вроде следующего: введите здесь описание изображения

Я отметил пробелы, которые я хотел бы обрезать или уменьшить. Обратите внимание: я знаю, что увеличение параметра ширины в функции geom_violin() действительно уменьшит это расстояние; однако я хочу сохранить ширину скрипок на уровне 0,5 и уменьшить только общую ширину графика (не затрагивая размеры скрипок). Также обратите внимание, что rel_widths функции plot_grid не помогает, так как мне нужно, чтобы оба графика были одинаковой ширины.

Я искал аналогичный вопрос и нашел этот; однако в ответе используется оператор «печать» и он предназначен только для одного графика. Может ли кто-нибудь обобщить этот ответ и для моего случая?

Для воспроизводимости моего примера я также перечисляю свои sessionInfo():

R version 3.3.2 (2016-10-31)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X Yosemite 10.10.5

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] cowplot_0.7.0   gridExtra_2.2.1 ggplot2_2.2.1   tidyr_0.6.1     dplyr_0.5.0    

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.10     assertthat_0.1   R6_2.2.0         plyr_1.8.4       gtable_0.2.0    
 [6] DBI_0.6-1        magrittr_1.5     scales_0.4.1     lazyeval_0.2.0   labeling_0.3    
[11] tools_3.3.2      munsell_0.4.3    colorspace_1.3-2 tibble_1.3.0    

EDIT Я только что сам нашел ответ. Расстояние между границами можно убрать, добавив + scale_x_discrete(expand = c(0,0)) к ggplots. Внутренний интервал контролируется параметром ширины.


person user8420488483439    schedule 20.04.2017    source источник


Ответы (2)


Это работает для меня, также я использовал фасетирование вместо других неуклюжих функций, таких как grid.arrange

library(dplyr)
library(tidyr)
library(ggplot2)

th1 <- theme_bw() + theme(legend.position = "none")

pi %>% 
  mutate(log_price = log10(price)) %>% 
  gather(Attribute, Value, log_price, depth) %>% 
  ggplot(aes(x = cut, y = Value, fill = color)) +
  geom_violin(width = 0.7) +
  th1 +
  facet_wrap(~ Attribute, scales = "free_y") 

Похоже, он автоматически устанавливает ширину около 0,85.

person Zafar    schedule 20.04.2017
comment
очень хороший; однако в вашем ответе есть две проблемы (1) средний разделитель между различными категориями разреза почти удален (я хочу, чтобы он был уменьшен, а не удален) и (2) что, если мне нужно, чтобы левый график был в логарифмическом масштабе, а правый - в линейном масштаб (и мне это действительно нужно), как я могу использовать ваш ответ для этого? Вот почему я использовал grid.arrange. В любом случае, я проголосовал за ваш ответ, потому что многому научился из вашего ответа. Спасибо. - person user8420488483439; 20.04.2017
comment
плюс, если вы используете geom_violin(width=0.5) вместо geom_violin() в своем ответе, форма вашего сюжета будет соответствовать сюжету в моем вопросе. - person user8420488483439; 20.04.2017
comment
1) Вы должны иметь возможность просто вставить туда geom_violin(width = 0.7) + или что-то подобное. Поиграйте, чтобы найти тот, который вам нравится больше всего. 2) Я обновлю ответ для преобразования журнала - person Zafar; 21.04.2017

Если вы хотите, чтобы ваш код оставался практически нетронутым, просто добавьте position = position_dodge(width = 0.7) в качестве параметра к вашему geom_violin. Измените номер ширины по своему усмотрению.

person ssp3nc3r    schedule 21.04.2017