Ggplot2 Keep Unused Levels Barplot

ggplot2 keep unused levels barplot

You need to set drop=FALSE on both scales (fill and x) like this:

library(ggplot2)
df <- data.frame(type=c("A", "A", "A", "B", "B"), group=rep("group1", 5))
df1 <- data.frame(type=c("A", "A", "A", "B", "B", "A", "A", "C", "B", "B"), group=c(rep("group1", 5),rep("group2", 5)))
df$type <- factor(df$type, levels=c("A","B", "C"))
df1$type <- factor(df1$type, levels=c("A","B", "C"))

plt <- ggplot(df, aes(x=type, fill=type)) +
geom_bar(position='dodge') +
scale_fill_discrete(drop=FALSE) +
scale_x_discrete(drop=FALSE)
plt1 <- ggplot(df1, aes(x=type, fill=type)) +
geom_bar(position='dodge') +
scale_fill_discrete(drop=FALSE) +
scale_x_discrete(drop=FALSE)

Edit:

I'm pretty sure this works. Forgot to change x to type instead of group and the position='dodge'! Just paste and test. The stat_bin deals with bins with zero counts. Check the docs.

How to make ggplot2 keep unused levels on data subset

The issue here is that a count of zero is not generated for sps = TAST, forage = CF. You can create that count using tidyr::complete. I've also added some dplyr functions to make the code cleaner. Assuming that your data frame is named df1 (as opposed to data, which is a base function name so not a good choice):

UPDATED: with stringsAsFactors = FALSE to address issues in comments.

library(dplyr)
library(tidyr)
library(ggplot2)

df1 <- read.table("data.txt", header = TRUE, stringsAsFactors = FALSE)
df1 %>%
filter(sps != "MICRO") %>%
group_by(sps) %>%
count(forage) %>%
ungroup %>%
complete(sps, forage, fill = list(n = 0)) %>%
ggplot(aes(sps, n)) + geom_col(aes(fill = forage), position = "dodge") +
scale_x_discrete(labels=c("Marmot","American Mink", "Weasel Spp.", "Red squirrel", "Chipmunk")) +
theme_classic() +
scale_fill_manual(values=c("#000000", "#666666", "#999999","#CCCCCC"), name = "Event") +
labs(x = "Species", y = "Number of observations")

Result:
Sample Image

Remove unused factor levels from a ggplot bar plot

One easy options is to use na.omit() on your data frame df to remove those rows with NA

ggplot(na.omit(df), aes(x=name,y=var1)) + geom_bar()

Given your update, the following

ggplot(df[!is.na(df$var1), ], aes(x=name,y=var1)) + geom_bar()

works OK and only considers NA in Var1. Given that you are only plotting name and Var, apply na.omit() to a data frame containing only those variables

ggplot(na.omit(df[, c("name", "var1")]), aes(x=name,y=var1)) + geom_bar()

ggplot2 0.9.0 automatically dropping unused factor levels from plot legend?

Yes, you want to add drop = FALSE to your colour scale:

ggplot(subset(df,fruit == "apple"),aes(x = year,y = qty,colour = fruit)) + 
geom_point() +
scale_colour_discrete(drop = FALSE)

Hide unused levels in ggplot legend

OK; the related issue 4511 gives the answer. Setting limits = force in scale_fill_manual did it.

Drop unused levels in facet_wrap in ggplot2

Specify scales = "free_y"

figure.gg = ggplot(data = df, aes(x = group1, y = est, ymin = lwr, ymax = upr)) +
geom_point(position = position_dodge(width = 0.5)) +
geom_errorbar(position = position_dodge(width = 0.5), width = 0.1) +
coord_flip() +
# Facet wrapped with one column using group 2s
facet_wrap(~group2, ncol = 1, strip.position = "right", scales = "free_y") +
ylab("estimate")

figure.gg

Move empty factor levels while maintaining order of non-empty levels in ggplot2

This was surprisingly tricky - given that all you need to do is order your levels correctly. I couldn't find anything in forcats that was directly appropriate, but we can write our own reordering function.

my_reorder <- function (fac, var) {
fac <- fct_reorder(fac, {{var}})
l <- levels(fac)
nonempty <- levels(factor(fac)) # I got this idea from droplevels()
empty <- setdiff(l, nonempty)
fct_relevel(fac, empty, nonempty)
fct_relevel(fac, empty, nonempty)
}

mtcars %>%
mutate(cyl = as.factor(cyl),
cyl = fct_expand(cyl, c("2", "4", "6", "8"))) %>%
group_by(cyl) %>%
summarize(meanMPG = mean(mpg)) %>%
ungroup() %>%
mutate(cyl = my_reorder(cyl, meanMPG)) %>%
ggplot(aes(x = cyl, y = meanMPG)) +
geom_col() +
scale_x_discrete(drop = FALSE, ) +
coord_flip() # shows empty level "2" on the top

ggplot2 barplot bar colour can't be changed properly

You can try these adjustments to
a) achieve the green bar colour and
b) simplify the code

  1. use geom_col rather than geom_bar with stat = "identity"
  2. swap x and y values and associated scales etc to avoid using coord_flip
  3. remove the limits argument in the call to scale_fill_manual
  4. convert Komp to a factor to control order of values in ggplot.
library(ggplot2)
library(forcats)
library(dplyr)


komp_cat <- c("Smartphone", "PC/Laptop", "Tablet", "TV", "Spielkonsole", "Smart-Watch", "E-Book-Reader", "Andere")

df1<- data.frame(
Komp = rep(komp_cat, 2),

groupW = c(
rep("ja", 8),
rep("nein", 8)),

valuesW = c (100-0, 100-23.9, 100-41.3, 100-30.9, 100-51.5, 100-73.2, 100-89.8, 100-98.9 ,0, 23.9, 41.3, 30.9, 51.5, 73.2, 89.8, 98.9)

)



df1 %>%
mutate(Komp = factor(Komp, levels = komp_cat)) %>%
ggplot( aes(x = valuesW, y = fct_rev(Komp), fill = rev(groupW))) +
geom_col(position = "dodge", color = "#8DAE10", show.legend = FALSE)+
xlab("Prozent")+
ylab("")+
scale_fill_manual(values = rep("#8DAE10", 2))+
geom_text(aes (label = round(valuesW,1)),
color = "black",
hjust = -0.35,
size = 4,
position = position_dodge(width = 0.9))+
geom_text(aes(x=0, label = groupW),
color = "white",
hjust = 0,
size = 5,
position = position_dodge(width = 0.9))+
scale_x_continuous(expand = c(0.04, 0), label = scales::comma, position = "bottom")

Sample Image

Created on 2021-09-22 by the reprex package (v2.0.0)



Related Topics



Leave a reply



Submit