5

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!

Jaap
  • 81,064
  • 34
  • 182
  • 193
Chitou
  • 81
  • 1
  • 6
  • Have a look at http://www.cookbook-r.com/Graphs/Legends_(ggplot2)/ and specifically the section on Modifying the appearance of the legend title and labels – infominer Jul 18 '16 at 19:42
  • @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 Jul 18 '16 at 20:04
  • http://stackoverflow.com/a/32583612/471093 – baptiste Jul 18 '16 at 21:02

1 Answers1

2

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)
Divi
  • 1,614
  • 13
  • 23