Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixed graph size in ggplot2

Tags:

r

ggplot2

I have some trouble with the ggplot2 package in R. I have a lot of data with similar structure and want to plot it. So I thougth I could write a function and use it in a loop. The problem is the different layout. In the example below, there is df1 containing coordinates (x and y) and values.

df1 <- data.frame(x_coord = c(1:100,1:100), y_coord = c(100:1, 1:100),
                  value = LETTERS[1:10])

Df2 is nearly the same but with longer value names:

df2 <- data.frame(x_coord = c(1:100,1:100), y_coord = c(100:1, 1:100),
                  value = paste0("longer_legend_entry_" ,LETTERS[1:10] ) )

My aim is to ggplot a graph of df1 and df2 with the same size. So I used coord_fixed() to keep the aspect ratio. But since I have to tell ggsave() a size in inches when saving the plot as PNG the different size of the legends is causing problems.

ggplot(data = df1, aes( x = x_coord, y = y_coord, color = value ) ) +
  geom_point() +
  theme( legend.position="bottom" ) +
  coord_fixed()

ggsave("plot1.png", width=3, height=3, dpi=100)

ggplot(data = df2, aes( x = x_coord, y = y_coord, color = value ) ) +
  geom_point() +
  theme( legend.position="bottom" ) +
  coord_fixed()

ggsave("plot2.png", width=3, height=3, dpi=100)

plot1

plot2

The graphs should have the same size in every PNG I produce even the legends are different.

Many thanks!

like image 303
Chitou Avatar asked Oct 30 '22 23:10

Chitou


1 Answers

It would be easier to put the legend on the right, provide number of rows to each legend item and then arrange the plots vertically as you want.

library(gridExtra)
g1 = ggplot(data = df1, aes(x = x_coord, y = y_coord, color = value)) +
  geom_point() +
  theme(legend.position="right") +
  coord_fixed() + guides(col = guide_legend(nrow = 2))

g2 = ggplot(data = df2, aes( x = x_coord, y = y_coord, color = value ) ) +
  geom_point() +
  theme( legend.position="right" ) +
  coord_fixed() + guides(col = guide_legend(nrow = 5))

gA = ggplotGrob(g1)
gB = ggplotGrob(g2)
gA$widths <- gB$widths
grid.arrange(gA, gB)

enter image description here

Edit: If you still want the legend on the bottom, use the following instead (but the right legend format is more visually appealing, in my opinion).

gA = ggplotGrob(g1)
gB = ggplotGrob(g2)
gB$heights <- gA$heights
grid.arrange(gA, gB)
like image 88
Divi Avatar answered Nov 15 '22 07:11

Divi