order ggplot by a separate column - r

I am trying to order this ggplot on the base of a different column which is not plot. Is that possible?
This is my subset of data
test<- structure(list(
Mutations = c(
"P9L",
"P9S",
"P9L",
"P9L",
"P9S",
"P9L",
"P9Q",
"P9S",
"P9S",
"P9L",
"P9S",
"P9L",
"P9S",
"P9L",
"P9Q",
"P9S",
"P9L",
"P9Q",
"P9S",
"P9L",
"P9S",
"P9L",
"S12P",
"S12P",
"S12P",
"S12P",
"S12P",
"S12P",
"S12P",
"C15S",
"C15S",
"C15F",
"C15F",
"C15F",
"C15F",
"C15F",
"C15S",
"C15F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F",
"L18F"
),
x = c(
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
9L,
12L,
12L,
12L,
12L,
12L,
12L,
12L,
15L,
15L,
15L,
15L,
15L,
15L,
15L,
15L,
15L,
18L,
18L,
18L,
18L,
18L,
18L,
18L,
18L,
18L,
18L,
18L,
18L
),
epi_week = c(
51L,
53L,
53L,
54L,
55L,
55L,
55L,
56L,
57L,
57L,
58L,
58L,
59L,
59L,
59L,
60L,
60L,
60L,
61L,
61L,
62L,
62L,
53L,
55L,
56L,
57L,
58L,
60L,
61L,
52L,
54L,
56L,
57L,
58L,
59L,
60L,
61L,
62L,
49L,
50L,
51L,
52L,
53L,
54L,
55L,
56L,
57L,
58L,
59L,
60L
),
n = c(
0.018412815,
0.015021782,
0.015021782,
0.010515247,
0.024205261,
0.032273681,
0.00806842,
0.023421032,
0.080858175,
0.048514905,
0.036714089,
0.073428178,
0.045506257,
0.053090633,
0.007584376,
0.040013338,
0.026675559,
0.00666889,
0.134355489,
0.023709792,
0.037509377,
0.012503126,
0.015021782,
0.01613684,
0.015614021,
0.016171635,
0.009178522,
0.013337779,
0.031613056,
0.027144408,
0.010515247,
0.007807011,
0.016171635,
0.018357045,
0.037921881,
0.013337779,
0.007903264,
0.012503126,
0.16722408,
0.353495679,
0.699686982,
1.221498371,
1.727504882,
3.238696109,
4.260125867,
3.70833008,
3.913535658,
2.065167508,
2.935153584,
2.734244748
),
mab = c(
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L
),
support = c(
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L,
1L
)
),
row.names = c(NA,
50L), class = "data.frame")
This is the code for the plot
p1 <- ggplot(test, aes(x = epi_week, y = Mutations, fill = n))+
geom_tile() + coord_equal() + scale_fill_gradient(trans = "log",low="white", high="darkgreen", guide_legend(title = "Percentage (%)", title.position = "top"), labels = function(x) sprintf("%.2f", x)) + theme(
# Hide panel borders and remove grid lines
panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
# Remove panel background
panel.background = element_blank(),
# Change axis line
axis.line = element_line(colour = "black"),
axis.text.y = element_text( hjust = 1, size=5,color="black")
)
p1
p1 + geom_tile(data=test, aes(colour=factor(support, c(1,2,3)), size=factor(support,c(1,2,3))), alpha=0) +
scale_colour_manual("Confidence", values=c("white", "c(1,2,3)), size=factor(support,c(1,2,3))), alpha=0) +
scale_colour_manual("Confidence", values=c("white", "blue4","red")) +
scale_size_manual("Confidence", values=c(0,0.2,0.2))
Mutations are names with a letter follow by a number and then another letter (e.g. R377L).
in my data I have a column x that have all the numbers.
How can I order my y axis in the ggplot (which is Mutations) by descending x values ?
I am also wondering if it is possible to have some column annotations aside the plot with data from the mab column?
THanks

You can use reorder(Mutations,-epi_week) to reorder Mutations based on the corresponding mean values of epi_week within each Mutation, see help page too:
ggplot(test, aes(x = epi_week, y = reorder(Mutations,-epi_week), fill = n))+
geom_tile() + coord_equal() +
scale_fill_gradient(trans = "log",low="white", high="darkgreen",
guide_legend(title = "Percentage (%)", title.position = "top"), labels = function(x) sprintf("%.2f", x)) + theme(
# Hide panel borders and remove grid lines
panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
# Remove panel background
panel.background = element_blank(),
# Change axis line
axis.line = element_line(colour = "black"),
axis.text.y = element_text( hjust = 1, size=5,color="black")
)
If you want to reorder by its numerical value after stripping it of strings, it will be:
ggplot(test, aes(x = epi_week,
y = reorder(Mutations,-as.numeric(gsub("[^0-9]*","",Mutations))),
fill = n))+
geom_tile() + coord_equal() + ylab("Mutation")

Related

How to add different boxplots to the same plot based on different data sources in ggplot /R?

Please find My Data below. Please note that picture below is an example of the design I wish to copy and does not correlate to My Data specifically.
My Data is stored in p. I have a continuous covariate p$ki67pro which denominate the percentage of cells actively dividing in a tumor sample (thus, ranging from 0 to 100). I have three different stages of the tumor, which correspond to p$WHO.Grade==1,2,3. Each sample represent a tumor patient that either had recurrence (p$recurrence==1) or not (p$recurrence==0).
Therefore:
head(p)
WHO.Grade recurrence ki67pro
1 1 0 1
2 2 0 12
3 1 0 3
9 1 0 3
10 1 0 5
11 1 0 3
I wish to produce the boxplot below. As you can see, there are four points which correspond to each p$WHO.Grade and and All samples. There are two boxplots per p$WHO.Grade + All.
Per p$WHO.Grade and All, I want one boxplot to represent p$ki67pro for recurrent tumors (p$recurrence==1) and the other boxplot to represent p$ki67pro for non-recurrent tumors (p$recurrence==0).
I.e.
p$ki67pro[p$WHO.Grade==1 & p$recurrence==0] versus
p$ki67pro[p$WHO.Grade==1 & p$recurrence==1]
p$ki67pro[p$WHO.Grade==2 & p$recurrence==0] versus
p$ki67pro[p$WHO.Grade==2 & p$recurrence==1]
p$ki67pro[p$WHO.Grade==3 & p$recurrence==0] versus
p$ki67pro[p$WHO.Grade==3 & p$recurrence==1]
And for All
p$ki67pro[p$recurrence==0] versus
p$ki67pro[p$recurrence==1]
I have used the following script so far, but I can figure out on how to get the All included. Please, note that there is only one case p$WHO.Grade==3
df <- data.frame(x = as.factor(c(p$WHO.Grade)),
y = c(p$ki67pro),
f = rep(c("ki67pro"), c(nrow(p))))
df <- df[!is.na(df$x),]
ggplot(df) +
geom_boxplot(aes(x, y, fill = f, colour = f), outlier.alpha = 0, position = position_dodge(width = 0.78)) +
scale_x_discrete(name = "", label=c("WHO-I","WHO-II","WHO-III","All")) +
scale_y_continuous(name="x", breaks=seq(0,30,5), limits=c(0,30)) +
stat_boxplot(aes(x, y, colour = f), geom = "errorbar", width = 0.3,position = position_dodge(0.7753)) +
geom_point(aes(x, y, fill = f, colour = f), size = 3, shape = 21, position = position_jitterdodge()) +
scale_fill_manual(values = c("#edf1f9", "#fcebeb"), name = "",
labels = c("", "")) +
scale_colour_manual(values = c("#1C73C2", "red"), name = "",
labels = c("","")) + theme(legend.position="none")
My Data p
p <- structure(list(WHO.Grade = c(1L, 2L, 1L, 1L, 1L, 1L, 3L, 2L,
1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
2L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L), recurrence = c(0L, 0L, 0L, 0L, 0L,
0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L,
1L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L,
1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L), ki67pro = c(1L, 12L,
3L, 3L, 5L, 3L, 20L, 25L, 7L, 4L, 5L, 12L, 3L, 15L, 4L, 5L, 7L,
8L, 3L, 12L, 10L, 4L, 10L, 7L, 3L, 2L, 3L, 7L, 4L, 7L, 10L, 4L,
5L, 5L, 3L, 5L, 2L, 5L, 3L, 3L, 3L, 4L, 4L, 3L, 2L, 5L, 1L, 5L,
2L, 3L, 1L, 2L, 3L, 3L, 5L, 4L, 20L, 5L, 0L, 4L, 3L, 0L, 3L,
4L, 1L, 2L, 20L, 2L, 3L, 5L, 4L, 8L, 1L, 4L, 5L, 4L, 3L, 6L,
12L, 3L, 4L, 4L, 2L, 5L, 3L, 3L, 3L, 2L, 5L, 4L, 2L, 3L, 4L,
3L, 3L, 2L, 2L, 4L, 7L, 4L, 3L, 4L, 2L, 3L, 6L, 2L, 3L, 10L,
5L, 10L, 3L, 10L, 3L, 4L, 5L, 2L, 4L, 3L, 4L, 4L, 4L, 5L, 3L,
12L, 5L, 4L, 3L, 2L, 4L, 3L, 4L, 2L, 1L, 6L, 1L, 4L, 12L, 3L,
4L, 3L, 2L, 6L, 5L, 4L, 3L, 4L, 4L, 4L, 3L, 5L, 4L, 5L, 4L, 1L,
3L, 3L, 4L, 0L, 3L)), class = "data.frame", row.names = c(1L,
2L, 3L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 18L, 19L, 20L,
21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L,
34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 44L, 45L, 46L, 47L, 48L,
49L, 50L, 51L, 52L, 53L, 54L, 55L, 57L, 59L, 60L, 61L, 62L, 63L,
64L, 65L, 66L, 67L, 68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 76L,
77L, 78L, 79L, 80L, 81L, 82L, 83L, 84L, 85L, 87L, 89L, 90L, 91L,
92L, 93L, 94L, 96L, 97L, 98L, 99L, 100L, 101L, 102L, 103L, 104L,
105L, 106L, 107L, 109L, 110L, 111L, 112L, 113L, 114L, 115L, 116L,
117L, 118L, 119L, 120L, 121L, 123L, 124L, 125L, 126L, 127L, 128L,
130L, 131L, 132L, 133L, 134L, 135L, 136L, 137L, 138L, 139L, 140L,
141L, 142L, 143L, 144L, 145L, 146L, 147L, 148L, 149L, 150L, 151L,
152L, 153L, 154L, 155L, 156L, 157L, 158L, 159L, 160L, 161L, 162L,
163L, 164L, 165L, 166L, 167L, 168L, 169L, 170L, 171L, 172L, 173L,
174L, 175L))
A trick that can be used is to create a new level in WHO.Grade, since it only has 3 levels. This should be a temporary level, so a good way of doing it is with package dplyr, function mutate.
Note that there is no need to create a new dataframe df.
library(ggplot2)
library(dplyr)
p %>%
bind_rows(p %>% mutate(WHO.Grade = 4)) %>%
mutate(WHO.Grade = factor(WHO.Grade),
recurrence = factor(recurrence)) %>%
ggplot(aes(WHO.Grade, ki67pro,
fill = recurrence, colour = recurrence)) +
geom_boxplot(outlier.alpha = 0,
position = position_dodge(width = 0.78, preserve = "single")) +
geom_point(size = 3, shape = 21,
position = position_jitterdodge()) +
scale_x_discrete(name = "",
label = c("WHO-I","WHO-II","WHO-III","All")) +
scale_y_continuous(name = "x", breaks=seq(0,30,5), limits=c(0,30)) +
scale_fill_manual(values = c("#edf1f9", "#fcebeb"), name = "",
labels = c("", "")) +
scale_colour_manual(values = c("#1C73C2", "red"), name = "",
labels = c("","")) +
theme(legend.position="none")
What about something like this:
# here you duplicate your original data
p1 <- p
# how to catch the all
p1$WHO.Grade <- 'all'
p <- rbind(p1,p)
library(ggplot2)
ggplot(p) +
geom_boxplot(aes(as.factor(WHO.Grade),
y = ki67pro,
fill = factor(recurrence) ,
color = factor(recurrence) ),
outlier.alpha = 0 , position = position_dodge(width = 0.78)) +
# from here it's more or less your code
scale_x_discrete(name = "", label=c("WHO-I","WHO-II","WHO-III","All")) +
scale_y_continuous(name="x", breaks=seq(0,30,5), limits=c(0,30)) +
stat_boxplot(aes(as.factor(WHO.Grade),
y = ki67pro,
color = factor(recurrence) ),
geom = "errorbar", width = 0.3,position = position_dodge(0.7753)) +
geom_point(aes(as.factor(WHO.Grade),
y = ki67pro,
color = factor(recurrence) ),
size = 3, shape = 21, position = position_jitterdodge()) +
scale_fill_manual(values = c("#edf1f9", "#fcebeb"), name = "",
labels = c("", "")) +
scale_colour_manual(values = c("#1C73C2", "red"), name = "",
labels = c("","")) +
theme(legend.position="none",
panel.background = element_blank(),
axis.line = element_line(colour = "black"))
In case your dataset is too large for just doubling it in size you create two plots and put them next to each other via grid.arrange().
library(ggplot2)
library(gridExtra)
#the data
df <- data.frame(x = as.factor(c(p$WHO.Grade)),
y = p$ki67pro,
f = as.factor(p$recurrence))
df <- df[!is.na(df$x),]
# plot 1
plot1 <- ggplot(df) +
geom_boxplot(aes(x, y, fill = f, colour = f), outlier.alpha = 0, position = position_dodge(width = 0.78)) +
scale_x_discrete(name = "", label=c("WHO-I","WHO-II","WHO-III","All")) +
scale_y_continuous(name="x", breaks=seq(0,30,5), limits=c(0,30)) +
stat_boxplot(aes(x, y, colour = f), geom = "errorbar", width = 0.3,position = position_dodge(0.7753)) +
geom_point(aes(x, y, fill = f, colour = f), size = 3, shape = 21, position = position_jitterdodge()) +
scale_fill_manual(values = c("#edf1f9", "#fcebeb"), name = "",
labels = c("", "")) +
scale_colour_manual(values = c("#1C73C2", "red"), name = "",
labels = c("","")) + theme(legend.position="none") +
theme(plot.margin = unit(c(1,-0.5,1, 1), "cm"))
#plot 2
plot2 <- ggplot(df) +
geom_boxplot(aes(x = "All", y = y, fill = f, colour = f), outlier.alpha = 0, position = position_dodge(width = 0.78)) +
scale_x_discrete(name = "") +
scale_y_continuous(name="x", breaks=seq(0,30,5), limits=c(0,30)) +
stat_boxplot(aes(x = "All", y = y, colour = f), geom = "errorbar", width = 0.3,position = position_dodge(0.7753)) +
geom_point(aes(x = "All", y = y, fill = f, colour = f), size = 3, shape = 21, position = position_jitterdodge()) +
scale_fill_manual(values = c("#edf1f9", "#fcebeb"), name = "",
labels = c("", "")) +
scale_colour_manual(values = c("#1C73C2", "red"), name = "",
labels = c("","")) + theme(legend.position="none") +
theme(axis.line.y = element_blank(),
axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
plot.margin = unit(c(1,1,1, -0.5), "cm"))
#put it together
lm <- rbind(c(1,1,1,2))
grid.arrange(plot1, plot2, layout_matrix = lm)
If I understood correctly, you just want to show all of your data in the last boxplot.
You can do this easily by just duplicating the data while creating the data frame and labelling the duplicate with All.
df <- data.frame(x = as.factor(c(p$WHO.Grade, rep("All", nrow(p)))),
y = rep(c(p$ki67pro), 2),
f = "ki67pro")
The plotting remains the same and you can easily add recurrence.
However, the plot you're showing above looks weird as the All boxplot doesn't contain all the data.

Add secondary X-axis with facets

Seems that this topic has not been covered this since the ggplot2.2.2 update where old solutions like this one and this one no longer apply. Fortunately, the process is far simpler than before. One line of code and you have a secondary Y-axis (as shown here).
But I cannot get a secondary X-axis on my plots...
I am comparing a depth profile of metal concentrations along the sediment core. I would like to display carbon and phosphate concentrations as an geom_area behind the metal's concentration. The problem is that both carbon and phosphate concentrations are no on the same scale as the metal. Thus I need a second axis.
The theme is the following (taken from this website):
theme_new <- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black"), strip.text.x = element_text(size=10, angle=0, vjust=0), strip.background = element_blank(), strip.text.y = element_text(angle = 0), legend.position="none",panel.border = element_blank(), axis.text.x=element_text(angle=45,hjust=1)) # Axis tick label angle
And this code gives me a second Y-axis even though I specify it under X-axis.
ggplot(MasterTable)+
geom_line(aes(Depth,Conc.nM))+
geom_area(aes(Depth,Conc.uM, fill=Variable))+
scale_x_continuous("Depth (cm)", sec.axis = sec_axis(~ . *100, name = "Carbon & Phosphate"))+
scale_y_continuous("Metal concentration (nM)")+
coord_flip()+
theme_new+
theme(legend.position = "right")+
facet_grid(. ~ Assay, scales = "free")
Can anyone help me place the secondary axis on the top of the figure?
Thanks!!
dput of my MasterTable is the following:
structure(list(Depth = c(15L, 5L, 2L, -1L, -3L, -5L, -7L, -9L,
-11L, -13L, -15L, -17L, -19L, -21L, -23L, -25L, -27L, -29L, -31L,
15L, 5L, 2L, -1L, -3L, -5L, -7L, -9L, -11L, -13L, -15L, -17L,
-19L, -21L, -23L, -25L, -27L, -29L, -31L), Conc.nM = c(24L, 24L,
24L, 100L, 100L, 75L, 75L, 85L, 85L, 120L, 300L, 1000L, 200L,
240L, 240L, 800L, 1100L, 1500L, 2300L, 0L, 10L, 0L, 50L, 200L,
200L, 50L, 50L, 200L, 15L, 0L, 0L, 10L, 120L, 200L, 1500L, 2100L,
2000L, 2000L), Assay = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Instrument 1",
"Instrument 2"), class = "factor"), Conc.uM = c(0L, 0L, 0L, 1L,
4L, 10L, 10L, 10L, 5L, 7L, 10L, 14L, 14L, 14L, 14L, 13L, 12L,
12L, 12L, 1L, 1L, 1L, 4L, 6L, 9L, 11L, 11L, 8L, 8L, 8L, 20L,
10L, 9L, 9L, 9L, 10L, 10L, 10L), Variable = structure(c(2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L), .Label = c("Carbon", "Phosphate"), class = "factor")), .Names = c("Depth",
"Conc.nM", "Assay", "Conc.uM", "Variable"), class = "data.frame", row.names = c(NA,
-38L))
Thanks to Brian's answer, and modifying the theme proposed above, I got the following figure.
As he suggested, you have to first modify your data manually using something like this:
MasterTable$Conc.uM <- MasterTable$Conc.uM *100
Then, in the code, adjust your axis with the same correction factor as the one used above. Here is the code to make the figure.
ggplot(MasterTable)+
geom_line(aes(Depth,Conc.nM))+
geom_area(aes(Depth,Conc.uM, fill=Variable), alpha=0.6)+ #Area for second X-axis
geom_area(aes(Depth,Conc.nM), alpha=0.95)+
geom_point(aes(Depth,Conc.uM), size=1, shape=16, alpha=0.3)+ #Adding points for second X-axis
geom_point(aes(Depth,Conc.nM), size=1, shape=16, alpha=0.8)+
scale_fill_manual(values=colours) + scale_colour_manual(values=colours) +
labs(title="Sediment core", color="",fill="") + #Place legend title in both color="" and fill=""
scale_y_continuous("Metal concentration (nM)",
sec.axis = sec_axis(~ . /100, name = "[Pi] (uM) DOC (mg/L)"))+
scale_x_continuous("Depth (cm)", breaks=pretty_breaks(n=7))+
coord_flip()+ #Required to make a proper depth profile
theme_new+ #Reference to custom theme
facet_grid(. ~ Assay, scales = "free") #Scales makes that the axis size can change
Now I just have one problem left to solve. I would like for the tick marks and labels to be under the facet. Seems more logical and less busy than having it at the top of the figure.
From your code:
...
scale_x_continuous("Depth (cm)", sec.axis = sec_axis(~ . *100, name = "Carbon & Phosphate"))+
scale_y_continuous("Metal concentration (nM)") +
coord_flip() ...
Consider which primary axis you want "Carbon & Phosphate" to be parallel to. Also consider what "x-axis" and "y-axis" mean in the context of using coord_flip.
TL;DR: Just move your secondary axis into scale_y_continuous.

Bars in geom_bar have unwanted different widths when using facet_wrap

I can'd find a solution for the following problem(s). I would appreciate some help a lot!
The following code produces bar charts using facet. However, due to "extra space" ggplot2 has in some groups it makes the bars much wider, even if I specify a width of 0.1 or similar. I find that very annoying since it makes it look very unprofessional. I want all the bars to look the same (except for the fill). I hope somebody can tell me how to fix this.
Secondly, how can I reorder the different classes in the facet windows so that the order is always C1, C2 ... C5, M, F, All where applicable. I tried it with ordering the levels of the factor, but since not all classes are present in every graph part it did not work, or at least I assume that was the reason.
Thirdly, how can I reduce the space between the bars? So that the whole graph is more compressed. Even if I make the image smaller for exporting, R will scale the bars smaller but the spaces between the bars are still huge.
I would appreciate feedback for any of those answers!
My Data:
http://pastebin.com/embed_iframe.php?i=kNVnmcR1
My Code:
library(dplyr)
library(gdata)
library(ggplot2)
library(directlabels)
library(scales)
all<-read.xls('all_auto_visual_c.xls')
all$station<-as.factor(all$station)
#all$group.new<-factor(all$group, levels=c('C. hyperboreus','C. glacialis','Special Calanus','M. longa','Pseudocalanus sp.','Copepoda'))
allp <- ggplot(data = all, aes(x=shortname2, y=perc_correct, group=group,fill=sample_size)) +
geom_bar(aes(fill=sample_size),stat="identity", position="dodge", width=0.1, colour="NA") + scale_fill_gradient("Sample size (n)",low="lightblue",high="navyblue")+
facet_wrap(group~station,ncol=2,scales="free_x")+
xlab("Species and stages") + ylab("Automatic identification and visual validation concur (%)") +
ggtitle("Visual validation of predictions") +
theme_bw() +
theme(plot.title = element_text(lineheight=.8, face="bold", size=20,vjust=1), axis.text.x = element_text(colour="grey20",size=12,angle=0,hjust=.5,vjust=.5,face="bold"), axis.text.y = element_text(colour="grey20",size=12,angle=0,hjust=1,vjust=0,face="bold"), axis.title.x = element_text(colour="grey20",size=15,angle=0,hjust=.5,vjust=0,face="bold"), axis.title.y = element_text(colour="grey20",size=15,angle=90,hjust=.5,vjust=1,face="bold"),legend.position="none", strip.text.x = element_text(size = 12, face="bold", colour = "black", angle = 0), strip.text.y = element_text(size = 12, face="bold", colour = "black"))
allp
#ggsave(allp, file="auto_visual_stackover.jpeg", height= 11, width= 8.5, dpi= 400,)
The current graph that needs some fixing:
Thanks a lot!
Here what I did after suggestion from Gregor. Using geom_segment and geom_point makes a nice graph as I think.
library(ggplot2)
all<-read.xls('all_auto_visual_c.xls')
all$station<-as.factor(all$station)
all$group.new<-factor(all$group, levels=c('C. hyperboreus','C. glacialis','Combined','M. longa','Pseudocalanus sp.','Copepoda'))
all$shortname2.new<-factor(all$shortname2, levels=c('All','F','M','C5','C4','C3','C2','C1','Micro', 'Oith','Tric','Cegg','Cnaup','C3&2','C2&1'))
allp<-ggplot(all, aes(x=perc_correct, y=shortname2.new)) +
geom_segment(aes(yend=shortname2.new), xend=0, colour="grey50") +
geom_point(size=4, aes(colour=sample_size)) +
scale_colour_gradient("Sample size (n)",low="lightblue",high="navyblue") +
geom_text(aes(label = perc_correct, hjust = -0.5)) +
theme_bw() +
theme(panel.grid.major.y = element_blank()) +
facet_grid(group.new~station,scales="free_y",space="free") +
xlab("Automatic identification and visual validation concur (%)") + ylab("Species and stages")+
ggtitle("Visual validation of predictions")+
theme_bw() +
theme(plot.title = element_text(lineheight=.8, face="bold", size=20,vjust=1), axis.text.x = element_text(colour="grey20",size=12,angle=0,hjust=.5,vjust=.5,face="bold"), axis.text.y = element_text(colour="grey20",size=12,angle=0,hjust=1,vjust=0,face="bold"), axis.title.x = element_text(colour="grey20",size=15,angle=0,hjust=.5,vjust=0,face="bold"), axis.title.y = element_text(colour="grey20",size=15,angle=90,hjust=.5,vjust=1,face="bold"),legend.position="none", strip.text.x = element_text(size = 12, face="bold", colour = "black", angle = 0), strip.text.y = element_text(size = 8, face="bold", colour = "black"))
allp
ggsave(allp, file="auto_visual_no_label.jpeg", height= 11, width= 8.5, dpi= 400,)
This is what it produces!
Assuming the bar widths are inversely proportional to the number of x-breaks, an appropriate scaling factor can be entered as a width aesthetic to control the width of the bars. But first, calculate the number of x-breaks in each panel, calculate the scaling factor, and put them back into the "all" data frame.
Updating to ggplot2 2.0.0 Each column mentioned in facet_wrap gets its own line in the strip. In the edit, a new label variable is setup in the dataframe so that the strip label remains on one line.
library(ggplot2)
library(plyr)
all = structure(list(station = structure(c(2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Station 101",
"Station 126"), class = "factor"), shortname2 = structure(c(2L,
7L, 8L, 11L, 1L, 5L, 7L, 8L, 11L, 1L, 2L, 3L, 5L, 7L, 8L, 12L,
11L, 1L, 6L, 8L, 15L, 14L, 9L, 10L, 4L, 6L, 2L, 7L, 8L, 11L,
1L, 5L, 7L, 8L, 11L, 1L, 2L, 3L, 5L, 7L, 8L, 12L, 11L, 1L, 8L,
11L, 1L, 15L, 14L, 13L, 9L, 10L), .Label = c("All", "C1", "C2",
"C2&1", "C3", "C3&2", "C4", "C5", "Cegg", "Cnaup", "F", "M",
"Micro", "Oith", "Tric"), class = "factor"), color = c(1L, 2L,
3L, 4L, 5L, 6L, 7L, 8L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L,
18L, 19L, 21L, 26L, 30L, 31L, 33L, 34L, 20L, 21L, 1L, 2L, 3L,
4L, 5L, 6L, 7L, 8L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L,
19L, 26L, 28L, 29L, 30L, 31L, 32L, 33L, 34L), group = structure(c(1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 4L, 4L, 4L, 4L, 4L, 4L, 4L,
4L, 6L, 5L, 3L, 3L, 3L, 3L, 6L, 6L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 3L, 3L,
3L, 3L, 3L), .Label = c("cgla", "Chyp", "Cope", "mlong", "pseudo",
"specC"), class = "factor"), sample_size = c(11L, 37L, 55L, 16L,
119L, 21L, 55L, 42L, 40L, 158L, 24L, 16L, 17L, 27L, 14L, 45L,
98L, 241L, 30L, 34L, 51L, 22L, 14L, 47L, 13L, 41L, 24L, 41L,
74L, 20L, 159L, 18L, 100L, 32L, 29L, 184L, 31L, 17L, 27L, 23L,
21L, 17L, 49L, 185L, 30L, 16L, 46L, 57L, 16L, 12L, 30L, 42L),
perc_correct = c(91L, 78L, 89L, 81L, 85L, 90L, 91L, 93L,
80L, 89L, 75L, 75L, 76L, 81L, 86L, 76L, 79L, 78L, 90L, 97L,
75L, 86L, 93L, 74L, 85L, 88L, 88L, 90L, 92L, 90L, 91L, 89L,
89L, 91L, 90L, 89L, 81L, 88L, 74L, 78L, 90L, 82L, 84L, 82L,
90L, 94L, 91L, 81L, 69L, 83L, 90L, 81L)), class = "data.frame", row.names = c(NA,
-52L))
all$station <- as.factor(all$station)
# Calculate scaling factor and insert into data frame
library(plyr)
N = ddply(all, .(station, group), function(x) length(row.names(x)))
N$Fac = N$V1 / max(N$V1)
all = merge(all, N[,-3], by = c("station", "group"))
all$label = paste(all$group, all$station, sep = ", ")
allp <- ggplot(data = all, aes(x=shortname2, y=perc_correct, group=group, fill=sample_size, width = .5*Fac)) +
geom_bar(stat="identity", position="dodge", colour="NA") +
scale_fill_gradient("Sample size (n)",low="lightblue",high="navyblue")+
facet_wrap(~label,ncol=2,scales="free_x") +
xlab("Species and stages") + ylab("Automatic identification and visual validation concur (%)") +
ggtitle("Visual validation of predictions") +
theme_bw() +
theme(plot.title = element_text(lineheight=.8, face="bold", size=20,vjust=1),
axis.text.x = element_text(colour="grey20",size=12,angle=0,hjust=.5,vjust=.5,face="bold"),
axis.text.y = element_text(colour="grey20",size=12,angle=0,hjust=1,vjust=0,face="bold"),
axis.title.x = element_text(colour="grey20",size=15,angle=0,hjust=.5,vjust=0,face="bold"),
axis.title.y = element_text(colour="grey20",size=15,angle=90,hjust=.5,vjust=1,face="bold"),
legend.position="none",
strip.text.x = element_text(size = 12, face="bold", colour = "black", angle = 0),
strip.text.y = element_text(size = 12, face="bold", colour = "black"))
allp

Variable label position in ggplot line chart

I have the following data frame summary created with dplyr
structure(list(maxrep = c(7L, 7L, 8L, 8L, 9L, 9L, 10L, 10L, 11L,
11L, 12L, 12L, 13L, 13L, 14L, 14L, 15L, 15L, 16L, 16L, 17L, 17L,
18L, 18L, 19L, 19L, 20L, 20L, 21L, 21L, 22L, 22L, 23L, 23L, 24L,
24L, 26L, 26L), div = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L,
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L,
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("Premier Division",
"Second Division"), class = "factor"), freq = c(1L, 10L, 4L,
39L, 26L, 89L, 73L, 146L, 107L, 162L, 117L, 133L, 121L, 125L,
116L, 91L, 110L, 65L, 95L, 43L, 75L, 38L, 43L, 24L, 38L, 16L,
36L, 5L, 15L, 2L, 9L, 7L, 9L, 1L, 3L, 3L, 2L, 1L)), .Names = c("maxrep",
"div", "freq"), class = c("grouped_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -38L))
My intention is to use ggplot2 to plot line graphs of 2 lines with different colour with text labels for each value.
What I did was
ggplot(df, aes(x=maxrep, y=freq, colour=div)) +
geom_line() +
geom_text(aes(label=freq), vjust=-.5)
The result was
Now my question: All the labels in the chart are above the points in respective lines. I want to have the labels for the different colours to be in different relative position, e.g. labels for cyan above the line, and labels for red below the line (i.e. variable vjust). Is there a way to do that?
Also, is there a way to get read of the letter a in the colour legend on the right?
What about plotting the lines separately wich differing vjust values? You can get rid of a in the legend setting show_guide = FALSE.
ggplot(df, aes(x=maxrep, y=freq, colour=div, label = freq)) +
geom_line() +
geom_text(data = df[df$div == "Second Division",], vjust=2, show_guide = FALSE) + geom_text(data = df[df$div == "Premier Division",], vjust=-2, show_guide = FALSE)
Which returns:
Create a new variable in the data.frame holding the vjust adjustment parameter:
df$pos <- c(2, -2)[(df$div == "Premier Division")+1]
And you could call vjust inside aes with the new pos vector:
ggplot(df, aes(x=maxrep, y=freq, colour=div)) +
geom_line() +
geom_text(aes(label=freq, vjust=pos))

How to plot exponential decay in geom_smooth in ggplot2 in R?

Data
> dput(new.gapdata.cc)
structure(list(gap.interval = structure(c(1L, 2L, 3L, 4L, 5L,
6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L,
19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 34L
), .Label = c("[0.0568,10.1]", "(10.1,20.1]", "(20.1,30.1]",
"(30.1,40.1]", "(40.1,50.1]", "(50.1,60.1]", "(60.1,70.1]", "(70.1,80.1]",
"(80.1,90.1]", "(90.1,100]", "(100,110]", "(110,120]", "(120,130]",
"(130,140]", "(140,150]", "(150,160]", "(160,170]", "(170,180]",
"(180,190]", "(190,200]", "(200,210]", "(210,220]", "(220,230]",
"(230,240]", "(240,250]", "(250,260]", "(260,270]", "(270,280]",
"(280,290]", "(290,300]", "(300,310]", "(310,320]", "(320,330]",
"(330,340]", "(340,350]", "(350,360]", "(360,370]", "(370,380]",
"(380,390]", "(390,400]", "(400,410]", "(410,420]", "(420,430]",
"(430,440]", "(440,450]", "(450,460]", "(460,470]", "(470,480]",
"(480,490]", "(490,500]", "(500,510]", "(510,520]", "(520,530]",
"(530,540]", "(540,550]", "(550,560]", "(560,570]", "(570,580]",
"(580,590]", "(590,600]", "(600,610]", "(610,620]", "(620,630]",
"(630,640]", "(640,650]", "(650,660]", "(660,670]", "(670,680]",
"(680,690]", "(690,700]", "(700,710]", "(710,720]", "(720,730]",
"(730,740]", "(740,750]"), class = "factor"), Vehicle.class = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Car following",
"Heavy-Vehicle following"), class = "factor"), PrecVehClass = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Car",
"Heavy-Vehicle"), class = "factor"), sd.speed = c(8.10631184218832,
11.4437550056097, 11.8038327709683, 10.8543703246156, 9.99720748006444,
9.44865875583687, 8.96606665646703, 8.49351869704553, 7.93669264490773,
8.13551032227591, 7.84202528436342, 8.0475744381228, 7.91648183675322,
7.43125313026708, 7.35410275703108, 7.60500908370333, 7.0498555301719,
7.55232413932399, 8.06598948864824, 6.76873032867712, 9.5638441069889,
8.04863015016668, 6.3210319215341, 4.64833690603376, 6.62719482422681,
6.64056528224281, 4.73744287133819, 7.47515815690314, 7.69289983159388,
0.306328206216196, 0.686563613792699), m.speed = c(7.49142882761648,
14.9015932672865, 23.2183766318976, 29.4281833927603, 33.2698195905316,
35.8151829762138, 37.5490804914733, 38.5477371278585, 39.3540677299243,
40.6919294171912, 41.1003756008852, 41.8182626555034, 43.0467747414578,
42.8363357874289, 43.4938190765401, 43.3542212600658, 45.4415004558705,
46.0292158248193, 45.2411112123218, 45.3142872888847, 45.8483490730252,
44.9081708678314, 48.91998889291, 47.3070826500395, 47.6670737425671,
46.3952054632908, 43.9972157634013, 51.2984320152685, 60.9675201903266,
44.7204961417801, 49.3765339447783), m.gapdist = c(7.7653843749647,
16.1638754974281, 25.4776617248361, 35.2445820779774, 44.9431006950918,
54.8030747287456, 64.7488740187079, 74.7493853439047, 84.7618392182203,
94.6265821702835, 104.858371321352, 114.633780836178, 124.562176064196,
134.473095135859, 144.806940411055, 154.554692908294, 164.982952591097,
174.906212522406, 185.553895860064, 194.461299821333, 204.825162321106,
215.128853160835, 225.333436194581, 235.137188240688, 244.880475531984,
255.160919142993, 264.314402521448, 274.575498681999, 285.224335149303,
293.119840359603, 337.618758706201)), .Names = c("gap.interval",
"Vehicle.class", "PrecVehClass", "sd.speed", "m.speed", "m.gapdist"
), row.names = c(3L, 8L, 13L, 18L, 24L, 31L, 37L, 43L, 49L, 55L,
61L, 66L, 71L, 76L, 81L, 85L, 88L, 91L, 94L, 96L, 98L, 100L,
102L, 105L, 107L, 109L, 112L, 114L, 116L, 118L, 121L), class = "data.frame")
What I want to achieve
I have 'sd.speed/m.speed' as dependent variable and 'm.gapdist' as explanatory variable. When I do a scatter plot the trend seems to be exponential decay. So I want to get the summary statistics as well as the plot fitted on the data points. I used following code:
ggplot() +
geom_point(data=new.gapdata.cc,
aes(y=sd.speed/m.speed, x=m.gapdist, shape=interaction(Vehicle.class,PrecVehClass)),
size=3) +
geom_smooth(data=new.gapdata.cc,
mapping = aes(y= sd.speed/m.speed, x=m.gapdist,
linetype=interaction(Vehicle.class,PrecVehClass)), method="lm", formula = log(y) ~ x,
se=F, size=1, color="black")
Question
This does not plot the exponential decay curve on the points. How can I fit the curve on points?

Resources