0
votes

I have a problem showing the legend in a ggplot. My data changes every day, and sometimes I have about 20 data points, sometimes only 5 data points.

The plot legend exceeds the limits of the diagram. But plotting it low scaled all the time is not a good option.

Here is a plot:

require(data.table)
require(ggplot2)

df <- data.table(name = c("A12345678901234567890", "B12345678901234567890", "C12345678901234567890", "D12345678901234567890", "E12345678901234567890", "F12345678901234567890", "G12345678901234567890", "H12345678901234567890", "I12345678901234567890"), val = runif(n = 9))

plotcolors <- rainbow(df[,.N, by = name][,.N], end = 0.65)
p <- ggplot(data = df)
p <- p + 
  scale_fill_manual(values = plotcolors) + 
  aes(x = name, y = val, fill = name) +
  theme(axis.text.x=element_blank(), legend.position = "bottom", text = element_text(size = 10), legend.text = element_text(size = 10), legend.title = element_text(size = 10), plot.margin = margin(10, 10, 10, 10, "pt")) + 
  xlab(NULL) +
  scale_y_continuous()
p <- p + geom_bar(stat = "identity", colour = "black")

print(p)

Outputting it on a square canvas writes the legend off range. Is it possible to create a kind of auto scale?


Update 2020-06-08:

This is how the plot looks like: enter image description here

The amount of curves differs. So the legend changes, and I need to adjust the size manually. I might calculate the size by counting the characters for each element and try to estimate the possible scaling. But it would be nice, if ggplot2 does it by itself.

1

1 Answers

1
votes

To my knowledge, no such legend autoscaling exists in ggplot. Making the plot larger (either via ggsave or by just making the device larger) can help to fit the legend into the plot.

But in the example given here, you are going to have a much easier time labeling the x-axis properly, because you are mapping the same variable to x and fill. You don't really need fill but you can still add it, ideally without a legend.

If you still want to modify the layout of the legend, look into guide_legend(), but it really is not the way to go here.

library(data.table)
library(ggplot2)


set.seed(42)
df <- data.table(name = c("A12345678901234567890", "B12345678901234567890", "C12345678901234567890", "D12345678901234567890", "E12345678901234567890", "F12345678901234567890", "G12345678901234567890", "H12345678901234567890", "I12345678901234567890"), val = runif(n = 9))

# Simple version
ggplot(df) + 
  geom_bar(aes(name, val), stat = "identity") + 
  theme(axis.text.x = element_text(angle = 90))

# Version with fill also mapped to name
ggplot(df) + 
  geom_bar(aes(name, val, fill = name), stat = "identity") + 
  theme(axis.text.x = element_text(angle = 90),
        legend.position = "none")