How to Label a Barplot Bar with Positive and Negative Bars with Ggplot2

Label a barplot by number of values with positive and negative bars

If you really want to color them conditionally to the sign, here a possible solution:

# fake df
df <- data.frame(Mean = c(1,3,-5),Labels = c("a","b","c"))
# here you decide to put white or black conditionally
df$color <- ifelse(df$Mean > 0, 'white','black')

library(ggplot2)
ggplot(df, aes(Labels, Mean))+
geom_bar(stat = "identity") +
theme_minimal() +
ggtitle(expression(paste("Air Pressure - C_PM", " - All Season"))) +
xlab("Air Pressure [hPa]") +
ylab("Shap Value") +
# here in aes() you put the color made
geom_text(aes(label=Mean, color=color), size=3.5, vjust = 1.8) +
# here you define the colors (it means "white" could be the color you want)
scale_color_manual(values = c("black" = "black", "white" = "white"))+
# you can remove the useless legend
theme(legend.position="none")

Sample Image

Controlling the position of geom_text labels in a bar plot with positive and negative values and facets with different scales

You can use hjust as an aesthetic mapping. If you set it to 0.5 - sign(value)/2 it will be 0 for the positive bars and 1 for the negative bars, as desired.

data_long %>% filter(score != 2,
score != "X") %>%
ggplot(aes(x = value, y=name, fill=sig))+
geom_bar(stat="identity") +
scale_fill_manual(values=c("grey", "firebrick")) +
scale_x_continuous(limits = ~ c(-1, 1) * max(abs(.x)),
labels = scales::percent) +
facet_wrap(~score, scales = "free_x") +
theme(legend.position = "none") +
geom_text(aes(label=label,
x = value, hjust = 0.5 - sign(value)/2), size = 3) +
labs(x = "Deviation From Expected Value",
y = "Group",
title = "Deviations From Expected Value by Score",
caption = "Red bars statistically significant")

Sample Image

How to label a barplot bar with positive and negative bars with ggplot2

This does the trick

library(plyr)
library(ggplot2)
library(scales)
dtf <- data.frame(x = c("ETB", "PMA", "PER", "KON", "TRA",
"DDR", "BUM", "MAT", "HED", "EXP"),
y = c(.02, .11, -.01, -.03, -.03, .02, .1, -.01, -.02, 0.06))
ggplot(dtf, aes(x, y)) +
geom_bar(stat = "identity", aes(fill = x), legend = FALSE) +
geom_text(aes(label = paste(y * 100, "%"),
vjust = ifelse(y >= 0, 0, 1))) +
scale_y_continuous("Anteil in Prozent", labels = percent_format()) +
opts(axis.title.x = theme_blank())

Sample Image

How to label negative and postive values on each bar in a grouped barplot in ggplot2

You can use aes(x,y) instead of vjust:

geom_text(aes(label= Value, 
x=Date,
y=Value+ifelse(Value>=0,0.01, -0.5)),
position = position_dodge(width = 0.9),
vjust = -0.5 , size= 3)

Sample Image

Barplot with negative values in different color

Add an ifelse condition to col

a <- barplot(df$value,
names=label,
col= ifelse(df$value < 0,"red","blue"),
xaxt = "n", yaxt = "n"
)

Refer Change colours of particular bars in a bar chart

How to split negative and positive bars by zero line in barplot?

Change "dodge" to "stack" in

geom_col(position = "stack")

Output

How to properly align labels on top of bars when using positive and negative values

You can actually set the hjust as an aesthetic variable, instead of giving all labels the same hjust value. Just give it a 1 for negative values and a 0 for positive values by doing hjust = value < 0 inside the aes call - the resulting logical vector will be implicitly converted to 1s and 0s:

df %>%
pivot_longer(-c(Letter)) %>%
mutate(value = ifelse(name == 'X', value * -1, value)) %>%
ggplot(aes(x = Letter, y = value, fill = name)) +
geom_bar(stat = 'identity', color = 'black', alpha = 0.7) +
geom_text(aes(label = format(abs(value), big.mark = '.'), hjust = value < 0),
size = 3, fontface = 'bold') +
scale_x_discrete(limits = rev(unique(df$Letter))) +
scale_y_continuous(labels = function(x) scales::comma(abs(x)),
breaks = scales::pretty_breaks(10)) +
coord_flip()

Sample Image

Put labels over negative and positive geom_bar

Pass position of geom_text on y axis with y = Value + 2 * sign(Value)

library(ggplot2)
ggplot(dat, aes(Types, Value)) +
geom_bar(stat = "identity" ,color = "#FFFFFF" , fill = "dodgerblue3") +
geom_text(aes(y = Value + 2 * sign(Value), label = Value),
position = position_dodge(width = 0.9),
size = 3.5 , angle = 90)

Sample Image

Another plot with minor visual tweaks that I do on my plots:

As you have numbers with bars you don't need y-axis (it's redundant).

ggplot(dat, aes(Types, Value)) + 
geom_bar(stat = "identity", color = "black" , fill = "grey",
size = 0.7, width = 0.9) +
geom_text(aes(y = Value + 2 * sign(Value), label = Value),
position = position_dodge(width = 0.9),
size = 5) +
theme_classic() +
theme(axis.text.x = element_text(size = 12),
axis.title = element_text(size = 20),
axis.text.y = element_blank(),
axis.line = element_blank(),
axis.ticks = element_blank())

Sample Image



Related Topics



Leave a reply



Submit