Сохранить размер панели для разных номеров панелей в ggplot - PullRequest
2 голосов
/ 06 ноября 2019

Я хочу построить две фигуры из разных фреймов данных, а затем объединить их в одну фигуру (конечная фигура более сложная). На каждом рисунке показано подмножество данных по двум категориальным переменным (скажем, «пол» и «круг»). Построенные данные имеют одинаковый тип на обеих фигурах. Каждый набор данных отличается по количеству уровней этих категориальных переменных.

Например, вот фиктивные данные, нанесенные на сетку 3 x 2:

require(ggplot2)
set.seed(10)

# Mock data
N <- 10
rounds <- c("A", "B", "C")
NROUNDS <- length(rounds)

df1 <- data.frame(
    Age = 1:N, 
    Response = rnorm(N*2*NROUNDS), 
    Sex = rep(c("M", "F"), each = N), 
    Round = rep(rounds, each = N*2)
)

# Dimension parameters
panel_width <- 2.5
panel_height <- 1.5
ylims <- c(-4, 4)
units <- "in"
panel_spacing <- 0.1
plot_mar <- 0.25

total_x_margin <- panel_spacing + plot_mar*2
total_y_margin <- panel_spacing*(NROUNDS-1) + plot_mar*2

# Plot the figure
six_panel_plot <- ggplot(df1, aes(x = Age, y = Response)) + 
    geom_line(lwd = 2, color = "#CC79A7") + 
    facet_grid(rows = vars(Round), cols = vars(Sex)) + 
    ylim(ylims) + 
    theme(
        panel.spacing.x = unit(panel_spacing, units),
        panel.spacing.y = unit(panel_spacing, units),
        plot.margin = margin(plot_mar, plot_mar, plot_mar, plot_mar, units)
    ) + theme_bw()

# Save the figure
ggsave("six_panel_plot.png", six_panel_plot, 
    width = total_x_margin + panel_width*2, 
    height = total_y_margin + panel_height*NROUNDS)

six_panel_plot

Я попытался настроитьРазмер рисунка зависит от количества панелей в каждом измерении и размера полей. Однако, если создать аналогичную фигуру в сетке 4 x 2, размеры отдельных панелей не будут такими же, как на предыдущем рисунке.

# Mock data
N <- 10
rounds <- c("A", "B", "C", "D")
NROUNDS <- length(rounds)

df2 <- data.frame(
    Age = 1:N, 
    Response = rnorm(N*2*NROUNDS), 
    Sex = rep(c("M", "F"), each = N), 
    Round = rep(rounds, each = N*2)
)


# Dimension parameters
panel_width <- 2.5
panel_height <- 1.5
ylims <- c(-4, 4)
units <- "in"
panel_spacing <- 0.1
plot_mar <- 0.25

total_x_margin <- panel_spacing + plot_mar*2
total_y_margin <- panel_spacing*(NROUNDS-1) + plot_mar*2


eight_panel_plot <- ggplot(df2, aes(x = Age, y = Response)) + 
    geom_line(lwd = 2, color = "#CC79A7") + 
    facet_grid(rows = vars(Round), cols = vars(Sex)) + 
    ylim(ylims) + 
    theme(
        panel.spacing.x = unit(panel_spacing, units),
        panel.spacing.y = unit(panel_spacing, units),
        plot.margin = margin(plot_mar, plot_mar, plot_mar, plot_mar, units)
    ) + theme_bw()

ggsave("eight_panel_plot.png", eight_panel_plot, 
    width = total_x_margin + panel_width*2, 
    height = total_y_margin + panel_height*NROUNDS)

eight_panel_plot

Если я выровняю эти цифры в другом программном обеспечении (Inkscape, Illustrator и т. Д.), Панели будут иметь разные размеры.

Как сохранить размер отдельных панелей на фигурах (без простого наложения четырех фигур на первую фигуру)? Я хочу избежать использования дополнительных пакетов, это возможно только с ggplot2?

Ответы [ 2 ]

2 голосов
/ 07 ноября 2019

У меня нет решения только для ggplot, но я буду использовать некоторые пакеты, от которых зависит сам ggplot (grid & gtable), поэтому никаких дополнительных загрузок не требуется. Я предположил, что нужные единицы измерения были определены в дюймах, но их легко изменить.

library(grid)

# As per your post
panel_width <- 2.5
panel_height <- 1.5

# Convert plot to gtables
plots <- list(p8 = ggplotGrob(eight_panel_plot), 
              p6 = ggplotGrob(six_panel_plot))

plots <- lapply(plots, function(gt) {
  # Find the positions of panels
  panel_x <- unique(panel_cols(gt)$l)
  panel_y <- unique(panel_rows(gt)$t)
  # Change the sizes of these positions
  gt$widths[panel_x] <- unit(panel_width, "inch")
  gt$heights[panel_y] <- unit(panel_height, "inch")
  gt
})

ggsave("test1.png", plot = plots[[1]])
ggsave("test2.png", plot = plots[[2]])

test1.png:

enter image description here

test2.png:

enter image description here

0 голосов
/ 07 ноября 2019

вы можете попробовать egg :: set_panel_size ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...