How to add y value average text to geom_bar? - r

ggplot(aes(x=MALE, y=AMOUNT, fill=MALE)) + geom_bar(stat="summary", fun="mean") +
ylab("Avg Amount") + theme(axis.title.x = element_blank())
How can I add the y value to the top of the bars given I've already created stat='summary' & fun='mean' when I created the graph?

To add the y value as label on top of your bars you can do:
geom_text(aes(label = after_stat(y)), stat = "summary", fun = "mean", vjust = -.1)
Using mtcars as example data and with some additional formatting of the label:
library(ggplot2)
ggplot(mtcars, aes(x = factor(cyl), y = mpg, fill = factor(cyl))) +
geom_bar(stat = "summary", fun = "mean") +
geom_text(aes(label = after_stat(sprintf("%.1f", y))), stat = "summary", fun = "mean", vjust = -.1) +
ylab("Avg Amount") +
theme(axis.title.x = element_blank())

Related

How to make different patterns and colors in different category of data using ggplot in R?

I would like to make my data have different colors for species and different patterns for sex. However, I can only set to make it different colors according to the sex. Here is my data,
data
This is how I run my script,
#making bar plot
library(readr)
library(ggplot2)
# loading and checking the data
data_summary <- read_csv("trial.csv")
print(data_summary)
# coloured barplot
ggplot(data_summary, aes(x = factor(species), y = mean, fill = sex)) +
geom_bar(stat = "identity", position = "dodge", show.legend = FALSE) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
labs(x="", y="") + theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
scale_fill_manual(values=c("#870A30","#D3D3D3"))
This can be done using fill = interaction(..,..):
library(ggplot2)
ggplot(data_summary, aes(x = factor(species), y = mean, fill = interaction(species,sex))) +
geom_bar(stat = "identity", position = "dodge", show.legend = FALSE) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
labs(x="", y="") +
theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
scale_fill_manual(values= c("#870A30", '#009E73', '#CC79A7', "#D3D3D3"))
An option could be using ggplot_build and add a vector of four colors (you change this to what you want) to the fill column of the bars layer like this:
library(ggplot2)
p <- ggplot(data_summary, aes(x = factor(species), y = mean, fill = sex)) +
geom_bar(stat = "identity", position = "dodge", show.legend = FALSE) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
labs(x="", y="") + theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
scale_fill_manual(values=c("#870A30","#D3D3D3"))
q <- ggplot_build(p)
q$data[[1]]$fill <- c("#870A30","#D3D3D3", '#009E73', '#CC79A7')
q <- ggplot_gtable(q)
plot(q)
Created on 2023-01-02 with reprex v2.0.2
You can use ggpattern to get different patterns per sex and different colors per species:
library(ggplot2)
library(ggpattern)
ggplot(data_summary, aes(x = species, y = mean, fill = species, group = sex)) +
geom_col_pattern(position = "dodge", aes(pattern = sex),
pattern_fill = "white", pattern_color = "white",
pattern_angle = 45, show.legend = FALSE) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9),
width = 0.2, show.legend = FALSE) +
labs(x = NULL, y = NULL) +
theme_classic() +
theme(panel.border = element_rect(linewidth = 0.5, fill = NA)) +
ylim(0, 80) +
scale_fill_manual(values = c("#870A30" ,"#D3D3D3"))
There is a nice package called ggpattern which offers hatching for geoms. Unfortunately it is not available for the R version I am using.
But I would like to offer different alpha values for the fill color.
The alpha itself can defined like scale_alpha_manual(values = c(.5,1)).
library(ggplot2)
data_summary <- read.table(text = "
species,sex,mean,sd,tukey
species_a,female,67,4.17,a
species_b,male,62.2,4.8,a
species_b,female,61.3,6.43,a
species_a,male,49.7,16.2,a
", header = T, sep = ','
)
# coloured barplot
ggplot(data_summary, aes(x = factor(species), y = mean, fill = sex, alpha = species)) +
geom_bar(stat = "identity", position = "dodge", show.legend = FALSE) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position = position_dodge(0.9), width = 0.2, show.legend = FALSE) +
labs(x="", y="") + theme_bw() +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(legend.position = c(0.1, 0.75)) + ylim(0, 80) +
scale_fill_manual(values=c("#870A30","#D3D3D3")) +
scale_alpha_manual(values = c(.5,1))

How Can I Plot Confidence Intervals with Dotted Lines?

I have the following code:
ggplot(pred_grid,
aes(x = x,
y = y)) +
geom_smooth(
aes(
ymin = lwr2, ymax = upr2,
fill = group, colour = group), stat = "identity") +
theme_gray(base_size = 17) +
scale_x_continuous(labels = scales::comma) +
scale_y_continuous(labels = scales::comma)
I then attempted to add dashed lines to signify the confidence intervals using the following code.
ggplot(pred_grid,
aes(x = x,
y = y)) +
geom_smooth(
aes(
ymin = lwr2, ymax = upr2,
fill = brand, colour = brand), stat = "identity") +
geom_line(aes(y = lwr2), linetype = "dashed") +
geom_line(aes( y = upr2), linetype = "dashed") +
theme_gray(base_size = 17) +
scale_x_continuous(labels = scales::comma) +
scale_y_continuous(labels = scales::comma)
However, the chart comes back looking like this.
What am I doing wrong?

How to change y axis from count to prop?

With ggplot2 and GGally, I created this bar chart with proportions:
ggplot(mtcars, aes(x = factor(cyl), by = 1)) +
geom_bar(fill = "steelblue", stat = "prop") +
geom_text(aes(label = scales::percent(after_stat(prop), accuracy = 1)), stat = "prop", nudge_y = 0.5) +
theme_minimal() +
theme(aspect.ratio = 1.5)
However, on the y axis, I would like to change that to reflect the percentages on the bars. I would like to avoid hard coding the values like ylim = "40", but let it use the values in the chart.
Try this:
ggplot(mtcars, aes(x = cyl)) +
geom_bar(aes(y = ..prop..), fill = "steelblue", stat = "count") +
geom_text(aes(label = scales::percent(..prop..), y = ..prop.. ), stat= "count", vjust = -.5) +
ylim(0, 0.5) +
ylab("") +
theme_minimal() +
theme(aspect.ratio = 1.5)
Edit: if you want a factor on x axis try
ggplot(mtcars, aes(x = factor(cyl))) +
geom_bar(aes(y = (..count..)/sum(..count..)), fill = "steelblue", stat = "count") +
geom_text(aes(label = scales::percent(round((..count..)/sum(..count..), 2)),
y = ((..count..)/sum(..count..))), stat = "count", vjust = -.25) +
ylim(0, 0.5) +
ylab("") +
theme_minimal() +
theme(aspect.ratio = 1.5)
Edit2: with the GGally package you can use:
ggplot(mtcars, aes(x = factor(cyl), by = 1)) +
geom_bar(aes(y = ..prop..), fill = "steelblue", stat = "prop") +
geom_text(aes(label = scales::percent(..prop..), y = ..prop.. ), stat = "prop", vjust = -.5) +
ylim(0, 0.5) +
ylab("") +
theme_minimal() +
theme(aspect.ratio = 1.5)

ggplot bar chart does not show correctly on Shiny

When I create bar chart below in R, there was no problem but when I convert these code to shiny function, the problem is occur, could you help ?
Bar chart in normal R code:
path <- "WA_Fn-UseC_-HR-Employee-Attrition.csv (job attrition)"
data <-fread(path)
# bar chart function function
Categorical_vs_categorical_plot_2 <- function(data,group_col,fill_col){
data %>%
ggplot(aes_(x = fill_col, group = group_col)) +
geom_bar(aes(y = ..prop.., fill = factor(..x..)),
stat="count",
alpha = 0.7) +
geom_text(aes(label = scales::percent(..prop..), y = ..prop.. ),
stat= "count",
vjust = 2) +
labs(y = "Percentage", fill= "Education") +
facet_grid(~Attrition) +
theme_minimal()+
theme(legend.position = "none", plot.title = element_text(hjust = 0.5)) +
ggtitle("Attrition")
}
Categorical_vs_categorical_plot_2(data,~Attrition,~BusinessTravel)
Normal bar chart
Bar chart convert to shiny code [error occur, not show facet_grid and text value like normal bar chart above] :
output$cat_vs_cat_chart2 <- renderPlot({
data() %>%
#ggplot(aes_(x = input$cat_compare, group = ~Attrition)) +
ggplot(aes_(x = 'BusinessTravel', group = ~Attrition)) +
geom_bar(aes(y = ..prop.., fill = factor(..x..)),
stat="count",
alpha = 0.7) +
geom_text(aes(label = scales::percent(..prop..), y = ..prop.. ),
stat= "count",
vjust = 2) +
#labs(y = "Percentage", fill= "Education") +
facet_grid(~Attrition) +
theme_minimal()+
theme(legend.position = "none", plot.title = element_text(hjust = 0.5)) +
ggtitle("Attrition")
})
Error bar chart
[Update] I got answers by myself:
[version 1] If input column feature directly to bar chart: need to add ~ to each column feature:
output$cat_vs_cat_chart2 <- renderPlot({
data() %>%
ggplot(aes_(x = ~BusinessTravel, group = ~Attrition)) +
geom_bar(aes(y = ..prop.., fill = factor(..x..)),
stat="count",
alpha = 0.7) +
geom_text(aes(label = scales::percent(..prop..), y = ..prop.. ),
stat= "count",
vjust = 2) +
#labs(y = "Percentage", fill= "Education") +
facet_grid(~Attrition) +
theme_minimal()+
theme(legend.position = "none", plot.title = element_text(hjust = 0.5)) +
ggtitle("Attrition")
})
[version 2] If input column feature from input$ in shiny ui : need to use aes_string instead aes_:
output$cat_vs_cat_chart2 <- renderPlot({
data() %>%
ggplot(aes_string(x = input$cat_compare, group = "Attrition")) +
geom_bar(aes(y = ..prop.., fill = factor(..x..)),
stat="count",
alpha = 0.7) +
geom_text(aes(label = scales::percent(..prop..), y = ..prop.. ),
stat= "count",
vjust = 2) +
#labs(y = "Percentage", fill= "Education") +
facet_grid(~Attrition) +
theme_minimal()+
theme(legend.position = "none", plot.title = element_text(hjust = 0.5)) +
ggtitle("Attrition")
})

Specify colors, axis lines, and removal of background in ggplot2

Where and how do I specify colors, axis lines, and removal of background in geombar? Ultimately, I want to have one bar to be dark gray and one bar to be light gray. They are currently blue and pink which were defaults. I also want the the x and y to have axis lines, and the figure to have no gray background. I have everything else figured out, using the below code. Thank you for your help.
library(ggplot2)
dodge <- position_dodge(width = 0.9)
limits <- aes(ymax = myData$mean + myData$se,
ymin = myData$mean - myData$se)
p <- ggplot(data = myData, aes(x = names, y = mean, fill = names)) +
p + geom_bar(stat = "identity", position = dodge) +
geom_errorbar(limits, position = dodge, width = 0.9) +
theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),
axis.title.x=element_blank())
limits <- aes(ymax = myData$mean + myData$se,
ymin = myData$mean - myData$se)
p <- ggplot(data = myData, aes(x = factor(site), y = mean,
fill = factor(infectionstatus)))
p + geom_bar(stat = "identity",
position = position_dodge(0.9)) +
geom_errorbar(limits, position = position_dodge(0.9),
width = 0.25) +
labs(x = "Sites", y = "Average Calories in White Muscle Tissue") +
scale_fill_discrete(name = "Infection Status")
You probably wanted something like this:
# Generate data
myData <- data.frame(names = letters[1:2],
mean = 1:2,
SE = 0.1)
# Plot data
library(ggplot2)
ggplot(myData, aes(names, mean)) +
geom_bar(aes(fill = names),
stat = "identity", position = "dodge") +
geom_errorbar(aes(ymin = mean - SE, ymax = mean + SE),
position = position_dodge(width = 0.5), width = 0.5) +
labs(title = "Calorie Amount",
subtitle = "Averaged per Tissue",
x = NULL,
y = "Average Calories in White Muscle Tissue",
fill = "Infection Status") +
scale_fill_manual(values = c("grey40", "grey60")) +
theme_classic() +
theme(axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
axis.title.x = element_blank())
I used theme_classic() as it does most of the job when you want clean plot. And specified colors with scale_fill_manual(values = c("grey40", "grey60"))

Resources