5
votes

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!

1
Have a look at cookbook-r.com/Graphs/Legends_(ggplot2) and specifically the section on Modifying the appearance of the legend title and labels - infominer
@infominer Thanks for the advice but I need a soultion focusing on graph size, like "make the graph 2x2 and use as much space as necessary for legend. Maybe there is a way like save PNG with a fixed width but flexible height or something. - Chitou

1 Answers

2
votes

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)