Individual axis limits with scale(expand) and scale=free in facetted ggplots - r

library(ggplot2)
df <- data.frame(Treatment=c("A", "B","A","B"), Value=c(3,4, 20,2), SE=c(1,1,5,1), Type=c("c1","c1","c2","c2"))
p1 <- ggplot(df, aes(Treatment, Value,fill=Treatment)) +
geom_bar(stat="identity", col="Black") +
geom_errorbar(aes(ymax = Value + SE, ymin=Value), col="black") +
facet_wrap(~Type, scale="free_y") +
theme(panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA),
strip.background = element_blank())
p1
I want to remove the white space between bar and x-axis:
p1 + scale_y_continuous(expand = c(0,0))
This also removes white space between the geom and the maximum of the y-axis. One way to prevent this is to control the limits of the y-axis
p1 + scale_y_continuous(expand = c(0,0), limits=c(0,26))
But now panel c1 has lots of white space, as limits apparently overrides scale="free", which is especially irrating when the panels are arranged in columns.
So, i need to have the expand-argument and scale="free" active at the same time. Is it possible?

You may want to use a geom_blank():
Please be considerate and try not to confound the user! This type of transformation can be dangerous!
library(ggplot2)
df <- data.frame(Treatment=c("A", "B","A","B"), Value=c(3,4, 20,2), SE=c(1,1,5,1), Type=c("c1","c1","c2","c2"))
ggplot(df, aes(Treatment, Value,fill=Treatment)) +
geom_bar(stat="identity", col="Black") +
geom_errorbar(aes(ymax = Value + SE, ymin=Value), col="black") +
geom_blank(aes(y=Value + SE + 1)) +
facet_wrap(~Type, scale="free_y") +
theme(panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA),
strip.background = element_blank()) +
scale_y_continuous(expand = c(0,0))
Or:
ggplot(df, aes(Treatment, Value,fill=Treatment)) +
geom_bar(stat="identity", col="Black") +
geom_errorbar(aes(ymax = Value + SE, ymin=Value), col="black") +
geom_blank(aes(y=Value + 2 * SE)) +
facet_wrap(~Type, scale="free_y") +
theme(panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA),
strip.background = element_blank()) +
scale_y_continuous(expand = c(0,0))
Created on 2018-05-17 by the reprex package (v0.2.0).

Related

How to plot geom_line over bar chart grouped by x variable not fill variable?

I have a data frame df
Group Time_Period mean uci lci
1 A Before 4.712195 5.054539 4.369852
2 A After 5.881463 6.241784 5.521142
3 B Before 5.349754 5.872940 4.826567
4 B After 6.653595 7.246231 6.060959
I want to plot this to illustrate that there is no difference in the mean increase between groups. I tried the following :
ggplot(df, aes(x=Time_Period, y=mean, fill=Group)) +
geom_bar(stat="identity", position=position_dodge(width = 1), color="black") +
geom_point(position = position_dodge(width = 1))+
geom_line(aes(group=Group, color=Group), color=c("cyan4","firebrick","cyan4","firebrick"), size =1, position = position_dodge(width = 1)) +
geom_errorbar(aes(ymin=lci, ymax=uci), position=position_dodge(width = 1)) +
theme_bw() +
scale_y_continuous(limits=c(-0.2,8), breaks= seq(0,300,1), minor_breaks=seq(0,300,0.5)) +
theme(panel.grid.minor = element_line(colour="lightgrey", size=0.5)) +
theme(panel.grid.major = element_line(colour="grey", size=0.5)) +
labs(y="Sales", x="Time Period", fill="Category") +
theme(axis.text.x = element_text(face="bold", size=12)) +
theme(axis.text.y = element_text(face="bold", size=12)) +
theme(axis.title.x = element_text(face="bold", size=16)) +
theme(axis.title.y = element_text(face="bold", size=16)) +
theme(legend.text= element_text(face="bold", size=12)) +
theme(legend.title= element_text(face="bold", size=16))
which plots:
However my manager is concerned it is difficult to differentiate the two lines due to the overlap, so he told me to rearrange the columns so that x is Group and fill is Time Period.
I tried the following:
ggplot(df, aes(x=Group, y=mean, fill=Time_Period)) +
geom_bar(stat="identity", position=position_dodge(width = 1), color="black") +
geom_point(position = position_dodge(width = 1))+
geom_line(aes(group=Group), color="black", size =1, position = position_dodge(width = 1)) +
geom_errorbar(aes(ymin=lci, ymax=uci), position=position_dodge(width = 1)) +
theme_bw() +
scale_y_continuous(limits=c(-0.2,8), breaks= seq(0,300,1), minor_breaks=seq(0,300,0.5)) +
theme(panel.grid.minor = element_line(colour="lightgrey", size=0.5)) +
theme(panel.grid.major = element_line(colour="grey", size=0.5)) +
labs(y="Sales", x="Group", fill="Time Period") +
theme(axis.text.x = element_text(face="bold", size=12)) +
theme(axis.text.y = element_text(face="bold", size=12)) +
theme(axis.title.x = element_text(face="bold", size=16)) +
theme(axis.title.y = element_text(face="bold", size=16)) +
theme(legend.text= element_text(face="bold", size=12)) +
theme(legend.title= element_text(face="bold", size=16))
But I can't work out how to get the lines to plot correctly between the two bars instead of just vertically in the centre, even if I adjust the "width" argument for position_dodge:
Please could anyone advise me on how to fix the plot?
You're looking for position_dodge2(). There's a little about it on the ggplot2 dodge reference, and a little more in the actual code on Github. The relevant section below, with some emphasis added:
Dodging preserves the vertical position of an geom while adjusting the
horizontal position. position_dodge2 is a special case of position_dodge
for arranging box plots, which can have variable widths. position_dodge2
also works with bars and rectangles. But unlike position_dodge,
position_dodge2 works without a grouping variable in a layer.
So here's the code, with some of the theming removed.
library(tidyverse)
txt = "
Group Time_Period mean uci lci
1 A Before 4.712195 5.054539 4.369852
2 A After 5.881463 6.241784 5.521142
3 B Before 5.349754 5.872940 4.826567
4 B After 6.653595 7.246231 6.060959"
df <- read.table(text = txt, header = TRUE) %>%
mutate(Group = fct_relevel(Group, "A", "B")) %>%
mutate(Time_Period = fct_relevel(Time_Period, "Before", "After"))
ggplot(df, aes(x=Group, y=mean, fill=Time_Period)) +
geom_bar(stat="identity", position=position_dodge(width = 1), color="black") +
geom_point(position = position_dodge(width = 1))+
geom_line(aes(group=Group), color="black", size =1,
position = position_dodge2(width = 1)) +
geom_errorbar(aes(ymin=lci, ymax=uci), position=position_dodge(width = 1)) +
theme_bw() +
scale_y_continuous(limits=c(-0.2,8), breaks= seq(0,300,1), minor_breaks=seq(0,300,0.5)) +
labs(y="Sales", x="Group", fill="Time Period")
Created on 2019-11-21 by the reprex package (v0.3.0)

How to add label to geom_segment at the start of the segment?

I'm sure this is simple but I can't figure it out.
I have the following chart:
library(data.table)
library(magrittr)
library(ggplot2)
cambodia <-
data.table(Period = c("Funan", "Chenla/Zhenla","Khmer Empire","Dark Ages of Cambodia"),
StartDate = c(-500,550,802,1431),
EndDate = c(550,802,1431,1863),
Color = c("lightblue","lightgreen","lightyellow","pink")) %>%
extract(order(-StartDate)) %>%
extract(, Period := factor(Period,levels = Period))
ggplot() +
geom_segment(data=cambodia, aes(x=StartDate, xend=EndDate, y=Period, yend=Period, color=Color),
linetype=1, size=2) +
scale_colour_brewer(palette = "Pastel1")+
xlab("Date")+
ylab("Ruler")+
theme_bw() +
theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank()) +
theme(aspect.ratio = .2) +
theme(legend.position="none")
But I would like the labels to be off the axis and on the page. Either to the left or on top of the middle of the line. E.g.
Most of the examples of geom_text give me gobbledeegook. I can't seem to apply them to the factor data I have here. Do you know how to do this?
Thank you
Having the labels on the end of the segments might distort the visual mapping of segment length and location to year-range. You could put the labels in the middle of the segments instead.
library(data.table)
library(magrittr)
library(ggplot2)
library(stringr)
cambodia <-
data.table(Period = c("Funan", "Chenla/Zhenla","Khmer Empire","Dark Ages of Cambodia"),
StartDate = c(-500,550,802,1431),
EndDate = c(550,802,1431,1863),
Color = c("lightblue","lightgreen","lightyellow","pink")) %>%
extract(order(-StartDate)) %>%
extract(, Period := factor(Period,levels = Period))
ggplot(cambodia, aes(x=StartDate, xend=EndDate, y=Period, colour=Period)) +
geom_segment(aes(xend=EndDate, yend=Period), linetype=1, size=2) +
geom_label(aes(label=str_wrap(Period,12), x=(StartDate + EndDate)/2), size=3) +
scale_colour_brewer(palette = "Set1") +
xlab("Date")+ ylab("Ruler")+
theme_bw() +
theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank(),
aspect.ratio = .2,
legend.position="none",
axis.text.y=element_blank(),
axis.ticks.y=element_blank())
Or what about going minimal:
ggplot(cambodia, aes(x=StartDate, y=1)) +
geom_rect(aes(xmin=StartDate, xmax=EndDate, ymin=0.97, ymax=1.03, fill=Period),
show.legend=FALSE, colour="white", size=0.5) +
geom_label(aes(label=str_wrap(Period,12), x=(StartDate + EndDate)/2), size=3.5) +
geom_text(aes(label=StartDate, y=0.96), size=3.5) +
geom_text(aes(label=ifelse(EndDate==max(EndDate), EndDate,""), x=EndDate, y=0.96), size=3.5) +
scale_colour_brewer(palette = "Set1") +
scale_y_continuous(limits=c(0.95,1.05)) +
theme_void()
ggplot() +
geom_segment(data=cambodia, aes(x=StartDate, xend=EndDate, y=Period, yend=Period, color=Color),
linetype=1, size=2) +
geom_label(data=cambodia, aes(x=StartDate, y=Period, label = Period),
nudge_x = c(-300, -200, -200, -100)) +
scale_colour_brewer(palette = "Pastel1")+
xlab("Date")+
ylab("")+
theme_bw() +
theme(legend.position="none") +
theme(aspect.ratio = .2) +
theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank(),
axis.line.y = element_blank(), axis.text.y = element_blank(),
axis.ticks.y = element_blank())
You need to use element_blank() to remove the y axis elements and then use nudge_x argument in geom_label to offset the labels appropriately.

Change colour of bar ggplot2

I am making a bar graph trying to change the colour of my bars using this code, but it does not seem to be working. What is the problem?
ggplot(hd.m, aes(provinces, value)) + geom_bar(aes(fill="#0072B2"), position = "dodge", stat="identity") + scale_fill_discrete(guide=FALSE) + xlab("Provinces and Territories") + ylab("Percentage(%)") + ggtitle("Heart Disease Prevelance across Canada in 2008-2009") + theme_bw() + theme(panel.border = element_blank()) + theme(
plot.title = element_text(size=20),
axis.title.x = element_text(size=14), axis.title.y = element_text(size=14)) + geom_hline(yintercept=4.7)
Take the fill out of the aes.
library(ggplot2)
df <- data.frame(x = c("AB","BC","MB"), y = c(3.5,3.9,4.6))
# You have:
ggplot(df, aes(x,y)) + geom_bar(aes(fill="blue"), stat="identity")
# Try:
ggplot(df, aes(x,y)) + geom_bar(fill="blue", stat="identity")

How to specify different palettes and line size within a single ggplot2 plot

I'm displaying four distributions within the same ggplot2 graph with the following code (data downloadable there: https://www.dropbox.com/s/l5j7ckmm5s9lo8j/1.csv?dl=0):
require(reshape2)
library(ggplot2)
library(RColorBrewer)
fileName = "./1.csv" # downloadable there: https://www.dropbox.com/s/l5j7ckmm5s9lo8j/1.csv?dl=0
mydata = read.csv(fileName,sep=",", header=TRUE)
dataM = melt(mydata,c("bins"))
ggplot(data=dataM, aes(x=bins, y=value, colour=variable)) +
xlab("bins") + ylab("freq") + geom_line(size = .5, alpha = .9) +
scale_colour_brewer(type = "qual", palette = 7) +
geom_line(size = .5, alpha = .9) +
theme_bw() +
theme(plot.background = element_blank()
,panel.grid.minor = element_blank()
,axis.line = element_blank()
,legend.key = element_blank()
,legend.title = element_blank()) +
scale_y_continuous(expand=c(0,0)) +
scale_x_continuous(expand=c(0,0))
How to change this graph so that B, E and W appear according to a specific palette (say: scale_colour_brewer) with a width of .5, while R appears in scale_colour_brewer(type = "qual", palette = 7) with a width of 1?
You can call subsets of your data in seperate geom_line's:
ggplot() +
geom_line(data=dataM[dataM$variable!="R",], aes(x=bins, y=value, colour=variable), size = .5, alpha = .9) +
geom_line(data=dataM[dataM$variable=="R",], aes(x=bins, y=value, colour=variable), size = 1.5, alpha = .9) +
scale_colour_brewer(type = "qual", palette = 7) +
theme_bw() +
theme(plot.background = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(),
legend.key = element_blank(), legend.title = element_blank()) +
scale_y_continuous("freq", expand=c(0,0)) +
scale_x_continuous("bins", expand=c(0,0))
this gives:
Another solution (as suggested by #baptiste) is setting the size and colour scales manually:
ggplot(data=dataM, aes(x=bins, y=value, colour=variable, size = variable)) +
geom_line(alpha = .9) +
scale_colour_manual(breaks=c("B","E","W","R"), values=c("green","orange","blue","pink")) +
scale_size_manual(breaks=c("B","E","W","R"), values=c(0.5,0.5,0.5,1.5)) +
theme_bw() +
theme(plot.background = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(),
legend.key = element_blank(), legend.title = element_blank()) +
scale_y_continuous("freq", expand=c(0,0)) +
scale_x_continuous("bins", expand=c(0,0))
this gives more or less the same result:
ggplot(aes(x=bins, y=value, colour=variable)) +
geom_line(data=dataM[dataM$variable!="R",]) +
geom_line(data=dataM[dataM$variable=="R",])

Change plot title sizes in a facet_wrap multiplot

Can any help me change the title text size for these plots. i.e. make them larger?
Script
ggplot(NMPSCMOR, aes(Length, fill=Year)) +
geom_histogram(position="dodge", binwidth=60, colour="black") + xlim(0, 600) +
scale_fill_grey(start = 1, end = 0)+
geom_vline(data=ddply(NMPSCMOR, Year~Morphology~Sector2, numcolwise(mean)),
mapping=aes(xintercept=Length,color=Year), linetype=2, size=1) +
scale_color_grey(start=1,end=0)+
xlab("Length Class") +
ylab(expression(paste("Total Count"))) + #( ", m^2, ")", sep =
facet_wrap( ~ Morphology + Sector2, ncol=3, scales = "free") +
theme(
panel.grid.minor = element_blank(), #removes minor grid lines
panel.grid.major = element_blank())
In theme(), add strip.text = element_text(size=25) or whatever size you want.

Resources