Quantcast
Channel: Active questions tagged r - Stack Overflow
Viewing all articles
Browse latest Browse all 201945

How do I adapt the number of required colors for a geom_bar plot automatically?

$
0
0

I would like to make a bar chart for a column with differently colored bars using ggplot.

library(ggplot2)

set.seed(123)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

ggplot(df_a, aes(A1)) +
  geom_bar(fill = c("green", "blue", "red", "yellow", "black"))  +
  scale_x_discrete(drop = FALSE)

That works fine: enter image description here However, in such a small sample I cannot expect that all possible numbers are present. Here is an example, where this is the case:

set.seed(321)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

Using the ggplot from before...

ggplot(df_a, aes(A1)) +
  geom_bar(fill = c("green", "blue", "red", "yellow", "black"))  +
  scale_x_discrete(drop = FALSE)

...throws an error:

Error: Aesthetics must be either length 1 or the same as the data (3): fill

It seems, that a vector with exactly 3 colors is expected, as there are 3 bars to fill?

Why is that?

Is there a way to fill without checking the numbers first?

And forcing a predefined number of bars (even when empty)?

Edit:

A solution was suggested by AndS.

set.seed(321)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

ggplot(df_a, aes(A1)) +
  geom_bar(aes(fill = as.factor(A1)))  +
  scale_x_discrete(drop = FALSE)

In this case that would result in 4 bars (including 1 empty bar).

However, to get all 5 bars (including missing bars), one has to label the data:

set.seed(321)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

df_a[[1]] <- ordered(df_a[[1]], levels = c(0:4), labels = c(0, 1, 2, 3, 4))

ggplot(df_a, aes(A1)) +
  geom_bar(aes(fill = as.factor(A1)))  +
  scale_x_discrete(drop = FALSE)

Is there a way to avoid this? Like including the sampeling parameters to get the number of possible columns?

Number of required bars:

c_a <- c(0, 1, 2, 3, 4)

df_a <- data.frame(A1 = sample(c_a, 10, replace = TRUE))

length(c_a)

edit2: I found a solution that works for me:

set.seed(321)

c_a <- c(0, 1, 2, 3, 4)

df_a <- data.frame(A1 = sample(c_a, 10, replace = TRUE))

df_a[[1]] <- ordered(df_a[[1]], levels = c_a, labels = as.character(c_a))

ggplot(df_a, aes(A1)) +
  geom_bar(aes(fill = as.factor(A1)))  +
  scale_x_discrete(drop = FALSE)


Viewing all articles
Browse latest Browse all 201945

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>