2

I have created a barchart using ggplot() + geom_bar() functions, by ggplot2 package. I have also used coord_flip() to reverse the orientation of the bars and geom_text() to add the values at the top of each bar. Some of the bars have different colors, so there is a legend following the graph. What I am getting as result is a picture half occupied by the graph, half by the legend and with the values on top of the longest bars being cut off because of the small size of the graph.

Any ideas on how to enlarge the size of the graph and reduce the size of the legend, in order the values of the bars not to be cut off?

Thank you

This is my code on imaginary data:

labels <- c("A","B","C","D","E")
freq <- c(10.3678, 5.84554, 1.5673, 2.313, 7.111)

df <- as.data.frame(cbind(labels,freq))

type <- c("rich","poor","poor","poor","rich")

library(ggplot2)
ggplot(df, aes(x = reorder(labels,freq), y= freq, fill = type)) +
  geom_bar(stat = "identity", alpha = 1, width = 0.9)+
  coord_flip()+  
  xlab("")+
  ylab("Mean frequency")+
  scale_fill_manual(name = "Type", values = c("red", "blue")) +
  ggtitle("Mean frequency of different labels")+
  geom_text(label = sort(freq, decreasing = FALSE), size = 3.5, hjust = -0.2)

And this is the graph it gives as result: enter image description here

Rea Kalampaliki
  • 124
  • 3
  • 11

2 Answers2

2

There are a few fixes to this:

Change your Limits

As indicated by @Dave2e - see his response

Change the size of your output

The interesting thing about graphics in R is that the aspect ratio and resolution of the graphics device will change the result and look of a plot. When I ran your code... no clipping was observed. You can test this out creating the plot and then saving differently. If I take your default code, here's what I get with different arguments to width= and height= for ggsave() as a png:

ggsave('a1.png', width=10, height=5)

enter image description here

ggsave('a2.png', width=15, height=5)

enter image description here

Set an Expansion

The third way is to set an expansion to the scale limits. By default, ggplot2 actually adds some "padding" to the ends of a scale. So, if you set your limits from 0 to 10, you'll actually have a plot area that goes a bit beyond this (about 5% beyond by default). You can redefine that setting by using the expand= argument of scale_... commands in ggplot. So you can set this limit, for example in the following code:

labels <- c("A","B","C","D","E")
freq <- c(10.3678, 5.84554, 1.5673, 2.313, 7.111)
type <- c("rich","poor","poor","poor","rich")
df <- data.frame(labels, freq, type)

library(ggplot2)
ggplot(df, aes(x = reorder(labels,freq), y= freq, fill = type)) +
  geom_bar(stat = "identity", alpha = 1, width = 0.9)+
  coord_flip()+  
  xlab("")+
  ylab("Mean frequency")+
  scale_fill_manual(name = "Type", values = c("red", "blue")) +
  ggtitle("Mean frequency of different labels")+
  geom_text(label = freq, size = 3.5, hjust = -0.2) +
  scale_y_continuous(expand=expansion(mult=c(0,0.15)))

enter image description here

You can define the lower and upper expansion for an axis, so in the above code I've defined to set no expansion to the lower limit of the y scale and to use a multiplier of 0.15 (about 15%) to the upper limit. Default is 0.05, I believe (or 5%).

chemdork123
  • 12,369
  • 2
  • 16
  • 32
1

You can override the default limits on the y axis scale with with the ylim() function.

labels <- c("A","B","C","D","E")
freq <- c(10.3678, 5.84554, 1.5673, 2.313, 7.111)
type <- c("rich","poor","poor","poor","rich")
df <- data.frame(labels, freq, type)

#set the max y axis limit to allow enough room for the label
ylimitmax <- 11

library(ggplot2)
ggplot(df, aes(x = reorder(labels,freq), y= freq, fill = type)) +
   geom_bar(stat = "identity", alpha = 1, width = 0.9)+
   coord_flip()+  
   xlab("")+
   ylab("Mean frequency")+
   scale_fill_manual(name = "Type", values = c("red", "blue")) +
   ggtitle("Mean frequency of different labels")+
   ylim(0, ylimitmax) +
   geom_text(label = freq, size = 3.5, hjust = -0.2)

The script shows how to code the manual limits but you may want to automate the limit calculation with something like ylimitmax= max(freq) * 1.2.

enter image description here

Dave2e
  • 22,192
  • 18
  • 42
  • 50
  • Thank you! The automated phrase would be part of the code like this: `...+ ylim(0, ylimitmax) + ...` ? – Rea Kalampaliki Jun 19 '20 at 22:01
  • 1
    In my script above I set the variable for the max limit just before the ggplot function call. Thus I have ylim referencing this global variable "ymaxlimit". – Dave2e Jun 19 '20 at 22:06