1

I'm making many figures in ggplot2 using a for loop, but my data labels are extending beyond the plot margin. I've tried using expand, but it only works for some figures. When I try to use par(mar) I get this error message:

Error: Don't know how to add o to a plot.

I also tried just using ggsave to save as a really wide file, but 1) that looks odd and 2) that won't work for making so many different figures.

Does anyone know of any other workarounds? Ideally a way to have the inner plot margins automatically set per figure based on the length of the bars + data labels. Below is the code I'm using and an example figure (you can see the bar for 'x' is outside the margin). Thank you in advance!

for (i in each) {
  temp_plot = ggplot(data= subset(Data, Each == i)) + 
    geom_bar(stat = "identity", 
             aes(x = reorder(Letter, +Number), y = Number, fill = factor(Category))) + 
    xlab("Letters") + 
    ggtitle(paste0("Title"), subtitle = "Subtitle") + 
    coord_flip() + 
    theme_classic() + 
    theme(plot.title = element_text(hjust = 0.5, size=16), 
          plot.subtitle = element_text(hjust = 0.5)) +
    scale_fill_manual(values = c("#00358E", "#00AFD7"), 
                      name= "Category", 
                      labels=c("This","That")) +
    geom_text(family="Verdana", size=3, 
              aes(label=Number2, x=reorder(Letter, +Number), y=Number), 
              position=position_dodge(width=0.8), hjust=-0.001) + 
    scale_y_continuous(labels = comma, expand = c(0.01,0)) + 
    scale_x_discrete(labels = letters)
  ggsave(temp_plot, file=paste0("Example", i,".jpeg"))
}

Example plot

Z.Lin
  • 28,055
  • 6
  • 54
  • 94
  • 3
    My general idiom for this is to explicitly set `limits=c(0,b)` for `scale_y_continuous()` and ensure `b` is an a % out from that. Said % is something you'll need to figure out as we all have aesthetic preferences. If it's a one-off plot I just hardcode a # but if it's a series of similar ones (like this) I use that % computation method. – hrbrmstr Nov 16 '18 at 17:27
  • 2
    You can add `clip = off` inside `coord_flip()` similar to [this](https://stackoverflow.com/a/50202854/786542) – Tung Nov 16 '18 at 17:33
  • It's hard to say without a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). I'm not sure what exactly is going on with your `expand` argument in your y scale, but it looks like you're setting very very small padding or no padding around the range of your data. Look at the docs for `scale_*_continuous` and try out using `expand_scale` – camille Nov 16 '18 at 18:42
  • I don't think you can change the plot margins automatically to take into account the length of the text label in this example, because stretching & compressing the plot would affect the amount of buffer required, in x-axis terms. Perhaps you can orient the label inwards instead? Check out the accepted answer [here](https://stackoverflow.com/questions/17241182/how-to-make-geom-text-plot-within-the-canvass-bounds) for a discussion. In your case, that would be something like `hjust = "inward"` for `geom_text()`. – Z.Lin Dec 03 '18 at 09:29

2 Answers2

1

I figured out a simple solution: + ylim(0, 130000)

Teng Wen
  • 11
  • 1
1

scale_y_continuous(expand = expansion(mult = c(0, .1)) )

Jiaqi
  • 486
  • 4
  • 5