I would like the barplot labels to start at 0 on the y axis. Right now, I can adjust them wrt the end of the bar, but that's not what I want.
data.df <- data.frame(Proportions=c(.4,.2,.25,.4,.12,.16),Name=c("Label one","Label two","Label three","Label one","Label two","Label three"),group=c("group.one","group.one","group.one","group.two","group.two","group.two"))
ex.plot <-
ggplot(data.df, aes(x=Name,y=Proportions,fill=group))+
geom_bar(stat='identity')+
xlab(NULL)+
ylab(NULL)+
scale_y_continuous(limits=c(0,1))+
scale_fill_manual(values=c("#EDA45E","#DB7365"))+
guides(fill=FALSE)+
geom_text(aes(label=Name),angle=90,hjust=1)+
theme_bw()+
theme(strip.text.x = element_blank())+
theme(panel.grid.major.x = element_blank(),axis.text.x=element_blank(),
axis.title.y = element_blank())+
facet_wrap(~group,nrow=1)
plot(ex.plot)
Not what I want:
geom_text(aes(label=Name, y=0), angle=90, hjust=0)
hjust=0 means left-justified.
Map the y aesthetic to 0.
...
geom_text(aes(label = Name, y = 0), angle = 90, hjust = 0) +
...
Related
I'm trying to recreate a bar graph found on page 4 of the following report:
The figure has three bars with the first two stacked and the third dodged next to it. I've seen iterations of this question but none that recreate the figure in this exact way.
Here is the data:
a <- rep(c('RHB', 'FERS', 'CSRS'), 3)
b <- c(rep('Assets', 3), rep('Amount Past Due', 3),
rep('Actuarial Liability', 3))
c <- c(45.0, 122.5, 152.3, 47.2, 3.4, 4.8, 114.4, 143.4, 181.3)
df <- data.frame(a,b,c)
names(df) <- c('Fund', 'Condition', 'Value')
And what I've managed so far:
p <- ggplot(subset_data, aes(fill=Condition, y=Value, x=Fund)) +
geom_bar(position="stack", stat="identity") +
coord_flip()
I'm not partial to ggplot so if there's another tool that works better I'm ok using another package.
Taking some ideas from the link #aosmith posted.
You can call geom_bar twice, once with Assets and Amounts Past Due stacked, and again with just Actuarial Liability.
You can use width to make the bars thinner, then nudge one set of bars so the two geom_bar calls are not overlapping. I chose to make the width 0.3 and nudge by 0.3 so the edges just line up. If you nudge by more you will see a gap between the two bars.
Edit: add some more formatting and numeric labels
library(tidyverse)
library(scales)
df_al <- filter(df, Condition == 'Actuarial Liability')
df_xal <- filter(df, Condition != 'Actuarial Liability')
bar_width <- 0.3
hjust_lab <- 1.1
hjust_lab_small <- -0.2 # hjust for labels on small bars
ggplot() +
theme_classic() +
geom_bar(data = df_al,
aes(fill=Condition, y=Value, x=Fund),
position = position_nudge(x = -bar_width),
width = bar_width,
stat="identity") +
geom_bar(data = df_xal,
aes(fill=Condition, y=Value, x=Fund),
position="stack",
stat="identity",
width = bar_width) +
geom_text(data = df_al,
aes(label= dollar(Value, drop0trailing = TRUE), y=Value, x=Fund),
position = position_nudge(x = -bar_width),
hjust = hjust_lab) +
geom_text(data = df_xal,
aes(label= dollar(Value, drop0trailing = TRUE), y=Value, x=Fund),
position="stack",
hjust = ifelse(df_xal$Value < 5, hjust_lab_small, hjust_lab)) +
scale_fill_manual(values = c('firebrick3', 'lightsalmon', 'dodgerblue')) +
scale_y_continuous(breaks = seq(0,180, by = 20), labels = dollar) +
coord_flip() +
labs(x = NULL, y = NULL, fill = NULL) +
theme(legend.position = "bottom")
I think I would use the "sneaky facet" method, after adding a dummy variable to dodge the columns and making Fund a factor with the correct order:
df$not_liability <-df$Condition != "Actuarial Liability"
df$Fund <- factor(df$Fund, levels = c('RHB', 'FERS', 'CSRS'))
Most of the plotting code is then an attempt to copy the look of the supplied plot:
ggplot(df, aes(fill=Condition, y=Value, x=not_liability)) +
geom_bar(position = "stack", stat = "identity") +
scale_x_discrete(expand = c(0.5, 0.5)) +
scale_y_continuous(breaks = 0:10 * 20, labels = scales::dollar) +
coord_flip() +
facet_grid(Fund~., switch = "y") +
scale_fill_manual(values = c("#c00000", "#f7c290", "#0071bf"), name = "") +
theme_classic() +
theme(panel.spacing = unit(0, "points"),
strip.background = element_blank(),
axis.text.y = element_blank(),
axis.ticks.length.y = unit(0, "points"),
axis.title = element_blank(),
strip.placement = "outside",
strip.text = element_text(),
legend.position = "bottom",
panel.grid.major.x = element_line())
I am wondering how I can change the grid line on x value=0, marked with a cross in the image, in my graph to shows the change from +ive to -ive. I would like to have it marked red with the same thickness. Thank you
=== Updated based on the comment
#Mtoto: My apologies. Here is the script.
df.boxplot<- ggplot(melt(df[,c(2:7)]), aes(variable, value))
df.boxplot +
geom_boxplot(lwd=1.2)+ theme_economist() + scale_colour_economist()+
scale_y_continuous(minor_breaks=seq(-5, 10, 0.5),name="Linear Measurements (mm)", breaks=seq(-5, 10, 1)) +
theme(axis.title.x = element_text(face="bold", colour="Black", size=20),
axis.text.x = element_text(face="bold", colour="Black", vjust=0.5, size=20)) +
scale_x_discrete(name="",labels=c("T0 A","T1 B","Δ AB","T0 C","T1 D","Δ CD")) +
theme(axis.title.y = element_text(face="bold", colour="Black", size=30,margin=margin(0,20,0,0)),
axis.text.y = element_text(angle=90, vjust=1, size=20)) +
theme(panel.grid.minor = element_line(colour="White",size=0.2))+
theme(axis.ticks = element_blank())+
ggtitle(" Title")+
theme(plot.title = element_text(size=25,lineheight=2, hjust =0.5, vjust=0.5, margin = margin(20, 10, 20, 0)))
I would also like to add a gap (one x unit/level) between the first three boxplots and the second three boxplots. I tried adding a NA column and use drop=FALSE and it didn't work.
I think you want to look at geom_hline -- I'm sure this is a duplicate...
library(ggplot2)
df <- data.frame(x = gl(5, 25),
y = rnorm(125))
ggplot(df, aes(x, y)) +
geom_boxplot() +
geom_hline(aes(y_intercept = 0), color = "red")
I would like to produce a plot using facet_wrap that has a different y scale for each row of the wrap. In other words, with fixed scales on the same row, free scales on different rows, with a fixed x scale. Free scales doesn't give me exactly what I'm looking for, nor does facet_grid. If possible, I'd like to avoid creating 2 separate plots and then pasting them together. I'm looking for a result like the plot below, but with a y scale max of 300 for the first row, and an y scale max of 50 in the second row. Thanks for any help!
Here is my code:
library(ggplot2)
library(reshape)
# set up data frame
dat <- data.frame(jack = c(150,160,170),
surgeon = c(155,265,175),
snapper = c(10,15,12),
grouper = c(5,12,50))
dat$island<-c("Oahu","Hawaii","Maui")
df<-melt(dat)
# plot
ggplot(df, aes(fill=variable, y=value, x=island)) +
geom_bar(width = 0.85, position= position_dodge(width=0.5),stat="identity", colour="black") +
facet_wrap(~variable, scales = "free_y",ncol=2) +
theme_bw() +
theme(strip.text = element_text(size=15, face="bold"))+
theme(legend.position="none")+
theme(panel.grid.major = element_line(colour = "white", size = 0.2))+
theme(panel.grid.minor = element_line(colour = "white", size = 0.5))+
theme(axis.text.x = element_text(angle = 90, hjust =1, vjust =0.5, size=18))+
labs(y = expression(paste("Yearly catch (kg)")))
Drawing on one of the lower ranked answers from the link Eric commented, you can add a layer that blends into the background to enforce the axes.
Here I created a second data frame (df2) that puts a single point at "Hawaii" and the max value you wanted (300 or 50) for the four variable/fish types. By manually setting the color of the geom_point white, it fades into the background.
library(ggplot2)
library(reshape)
# set up data frame
dat <- data.frame(jack = c(150,160,170),
surgeon = c(155,265,175),
snapper = c(10,15,12),
grouper = c(5,12,50))
dat$island<-c("Oahu","Hawaii","Maui")
df<-melt(dat)
#> Using island as id variables
df2 <- data.frame(island = rep("Hawaii",4), variable = c("jack","surgeon","snapper","grouper"),value = c(300,300,50,50))
ggplot(df, aes(fill=variable, y=value, x=island)) +
geom_bar(width = 0.85, position= position_dodge(width=0.5),stat="identity", colour="black") +
geom_point(data = df2, aes(x = island, y = value), colour = "white") +
facet_wrap(~variable, scales = "free_y",ncol=2) +
theme_bw() +
theme(strip.text = element_text(size=15, face="bold"))+
theme(legend.position="none")+
theme(panel.grid.major = element_line(colour = "white", size = 0.2))+
theme(panel.grid.minor = element_line(colour = "white", size = 0.5))+
theme(axis.text.x = element_text(angle = 90, hjust =1, vjust =0.5, size=18))+
labs(y = expression(paste("Yearly catch (kg)")))
I have a simple problem but I can't figure out why it won't work -> I can't adjust the y scale range on my faceted bar plot:
# Data #
df<-as.data.frame(c("x","y","z","x","y","z","x","y","z","x","y","z"))
colnames(df)<-"x"
df$y<-c(10,15,20,5,25,45,10,10,20,40,20,5)
df$facet<-c(1,1,1,1,1,1,2,2,2,2,2,2)
df$group<-c("A","A","A","B","B","B","A","A","A","B","B","B")
# Plot #
ggplot(df, aes(x=x, y=y, fill=group)) +
facet_grid( ~ facet) +
scale_fill_manual(values=c("blue", "red")) +
geom_bar(position="dodge", stat="identity") +
theme(strip.text = element_text(face="bold", size=rel(1)),
strip.background = element_rect(fill="white", colour="white", size=1)) +
theme(panel.margin = unit(1, "lines")) +
scale_x_discrete(expand = c(0, 0)) +
theme(panel.grid.major.x = element_blank()) + theme(axis.ticks.x = element_blank()) +
theme(legend.background=element_blank()) +
scale_y_continuous("%", breaks=seq(0, 50, 10), minor_breaks=seq(0,50,5), expand = c(0, 0))
I would like the y-axis to go upto 50 but using scale_y_continuous strangely does not work, producing this result:
You need to add a limits argument in your scale_y_continuous :
scale_y_continuous("%", limits=c(0,50), breaks=seq(0, 50, 10), minor_breaks=seq(0,50,5), expand = c(0, 0))
Otherwise you just define the breaks position, not the axis values range.
I have a plot in ggplot that shows me for each category of "rating" the level of price in "bank" and "sistem". This is my code:
##fict
a<-c("rating1","rating2","rating3")
b<-c(1.2,1.2,1.3)
c<-c(1.6,1.4,1.6)
gg<-cbind('rating'=rep(a,2),'price'=c(b,c),'tipo'=rep(c("bank","sistem"),3))
gg<-as.data.frame(gg)
a<-rgb(red=150, green=191, blue=37, maxColorValue = 255)
b<-rgb(red=80, green=113, blue=14, maxColorValue = 255)
ggplot(gg, aes(x=tipo, y=price,width=1)) +
geom_bar(position='stack', stat='identity', fill=c(b,a), color='black') +
facet_wrap( ~ rating)+
theme_bw() + theme(axis.line = element_line(colour = "black"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank(),
strip.background = element_rect(colour = 'white', fill = 'white', size = 3),
axis.title.y=element_text(vjust=0.19),
axis.title.x=element_text(vjust=0.19)
#strip.text.x = element_text(colour = 'red', angle = 45, size = 10, hjust = 0.5, vjust = 0.5, face = 'bold')
) + xlab("My x label") +
ylab("My y label") +
labs(title = 'difference')
This code generates my plot.
I'd like to change 3 things:
I'd like that the labels rating shows in the bottom
I'd like that the "bank" and "sistem" labels disappear and change it with the legend with colors for bank and sistem.
If it's possible also put the legend under the x-axis title in horizontal way
Thank you
Upgrade comment to an answer.
library(ggplot2)
# your data - tweaked the code - there is no need to cbind within data.frame
# and names do not need to be in quotes
gg <- data.frame(rating=rep(c("rating1","rating2","rating3"),2),
price=c(c(1.2,1.2,1.3),c(1.6,1.4,1.6)),
tipo=rep(c("bank","sistem"),3))
a <- rgb(red=150, green=191, blue=37, maxColorValue = 255)
b <- rgb(red=80, green=113, blue=14, maxColorValue = 255)
# Plot
# use position dodge to get the bars side-by-side
# theme_classic removes grid lines and uses theme_bw()
# scale_fill_manual to manually specify the colours - by using fill = tipo in the
# aesthetic call of ggplot a legend will be generated
# scale_y_continuous - using expand starts the axis at exactly zero
ggplot(gg, aes(x=rating, y=price, fill=tipo)) +
geom_bar(position='dodge', stat='identity', color='black') +
theme_classic() +
scale_fill_manual(values = c(b,a)) +
scale_y_continuous(limit=c(0,2), expand=c(0,0)) +
labs(title = 'difference', x = "My x label", y = "My y label") +
theme(
axis.title.y=element_text(vjust=0.19),
axis.title.x=element_text(vjust=0.19) ,
legend.position = "bottom",
legend.title=element_blank())