2

I am trying to plot bar graphs on a map following this example: How to plot barchart onto ggplot2 map. This works fine but in contrast to the example I would like to add x and y axis. The problem is that the y range of the data differs considerably across the regions for which I would like to create the bar graphs.

In order to produce comparable graphs (i.e. where the y axis has an identical dimension), I apply the same y limits to all graphs and adjust the breaks for each graph. This is, however, not a good solution as some of the graphs (p2 in this case) have a large empty area above and below the bars. In order to make it work, I am looking for a method top crop the graphs to remove the empty areas, while at the same time maintaining the dimensions of the graph so that y axis can be compared.

library(dplyr)
library(ggplot2)

df <- data.frame(type = c("A", "B", "A", "B"), country = c("NLD", "NLD", "BEL", "BEL"), value = c(10, -10, 5, 2))

df1 <- filter(df, country == "NLD") 
p1 <- ggplot(data = df1) +
    geom_col(aes(x = type, y = value)) +
    scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks = seq(min(df1$value), max(df1$value), 2)) + 
    theme_bw()
p1


df2 <- filter(df, country == "BEL") 
p2 <- ggplot(data = df2) +
      geom_col(aes(x = type, y = value)) +
      scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks   = seq(min(df2$value), max(df2$value), 2)) +
      theme_bw()
    p2

1 Answers1

1

Have you tried coord_fixed for each of the plot? If you can control the width of each plot the same, the height of bars will be comparable.

library(dplyr)
library(ggplot2)
library(gridExtra)

df <- data.frame(type = c("A", "B", "A", "B"), country = c("NLD", "NLD", "BEL", "BEL"), value = c(10, -10, 5, 2))

df1 <- filter(df, country == "NLD") 
p1 <- ggplot(data = df1) +
  geom_col(aes(x = type, y = value)) +
  # scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks = seq(min(df1$value), max(df1$value), 2)) + 
  theme_bw()

df2 <- filter(df, country == "BEL") 
p2 <- ggplot(data = df2) +
  geom_col(aes(x = type, y = value)) +
  # scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks   = seq(min(df2$value), max(df2$value), 2)) +
  theme_bw()

x_range <- length(unique(df$type))
y_range1 <- max(df1$value) - min(df1$value)
y_range2 <- max(df2$value) - min(df2$value)

g1 <- p1 + coord_fixed(ratio = x_range / y_range1)
g2 <- p2 + coord_fixed(ratio = x_range / y_range1)

# example output
grid.arrange(g1, g2, nrow = 1)
GL_Li
  • 1,758
  • 1
  • 11
  • 25
  • This is a great simple solution that addresses my problem for 90%. However, for some of the individual plots I do not have data for all categories on the x-axis and, hence, this solution results in a distortion in the size of these figures. I welcome solutions that provide a universal solution. – Michiel van Dijk Dec 23 '17 at 17:20
  • Not sure whether this is what you want but you can add `scale_x_discrete(limits = levels(df$type))` to p1, p2, ..., to force all plots have the same `x-axis` so that each bar width will be the same across p1, p2, .... There will be a blank space if a type is missing. – GL_Li Dec 24 '17 at 01:39