R piechart managing legend in multiple plot - r

I am trying to write a code for multiple pie charts showing top 10 bacterial abundance during initial treatment days, mid treatment days and end of treatment days antibiotic usage for two drugs say X and Y . But in this plot I need to fix three points
putting Others at the end for all plots.
Add a common legend
add a common order so that all the successive pie charts take the bacteria order from the first. Not reorder them every time. So that it will be easier to compare by eye.
Can anyone please help?
My code is as bellow.
dput(xInitialDays)
structure(list(Dataset = c("Lachnospiraceae", "Bifidobacteriaceae",
"Oscillospiraceae", "Enterobacteriaceae", "Peptostreptococcaceae",
"Sutterellaceae", "Erysipelotrichaceae", "Peptoniphilaceae",
"Clostridiaceae", "Bacteroidaceae", "Others"), Values = c(41670.41,
22926.45, 21939.35, 15083.38, 11544.14, 10824.77, 9349.65, 6716.93,
4856.3, 3807.31, 20828.8), per = c(24.58, 13.52, 12.94, 8.9,
6.81, 6.38, 5.51, 3.96, 2.86, 2.25, 12.27)), row.names = c(1L,
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 65L), class = "data.frame")
allcols= 20
getPalette = colorRampPalette(brewer.pal(12, "Set3"))
fill=getPalette(allcols)
allcols<-fill
xInitialDays %>%
mutate(taxa = xInitialDays$Dataset) %>%
mutate(cols = fill[c(1:11)]) %>%
select(taxa,cols) -> ColAssgn
len = 11
xinidays <- function(){
xInitialDays%>%
ggplot(aes(x='',y=reorder(Values,Values),fill=Dataset))+
geom_bar(width=1,stat="identity")+
scale_fill_manual(breaks = ColAssgn$taxa,
values = ColAssgn$cols)+
theme_void()+
theme_classic() +
theme(legend.position = "top") +
coord_polar("y",start=0) +
theme(axis.line = element_blank())+
theme(axis.text = element_blank()) +
theme(axis.ticks = element_blank())+
labs(x = NULL, y = NULL, fill = NULL)+
ylab("Baseline")
}
order(xInitialDays$Values)
xinidays()
I have repeated the similar code for middays and final days and for X and Y.
> dput(xMidDays)
structure(list(Dataset = c("Bifidobacteriaceae", "Oscillospiraceae",
"Enterobacteriaceae", "Lachnospiraceae", "Erysipelotrichaceae",
"Sutterellaceae", "Akkermansiaceae", "Acidaminococcaceae", "Bacteroidaceae",
"Lactobacillaceae", "Others"), Values = c(41204.96, 22093.39,
21504.25, 19273.93, 14853.98, 7146.53, 6734.07, 4340.38, 3444.21,
2541.56, 18130.24), per = c(25.55, 13.7, 13.33, 11.95, 9.21,
4.43, 4.18, 2.69, 2.14, 1.58, 11.23)), row.names = c(1L, 2L,
3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 65L), class = "data.frame")
And I took this strategy bellow to select the same bacteria colours
taxalen <- xMidDays$Dataset[c(which(!(xMidDays$Dataset %in% ColAssgn$taxa)))]
for (count in 1:length(taxalen)){
if(length(taxalen) > 0){
len = len +1
ColAssgn %>%
rbind(c(taxalen[count],allcols[len])) -> ColAssgn
}
}
xmiddays <- function(){
xMidDays %>%
ggplot(aes(x='',y=reorder(Values,Values),fill = Dataset))+
geom_bar(width=1,stat="identity")+
scale_fill_manual(breaks = ColAssgn$taxa,
values = ColAssgn$cols)+
theme_void()+
theme_classic() +
theme(legend.position = "top") +
coord_polar("y",start=0) +
theme(axis.line = element_blank())+
theme(axis.text = element_blank()) +
theme(axis.ticks = element_blank())+
labs(x = NULL, y = NULL, fill = NULL)+
ylab("Mid Treatment")
}
xmiddays()
And for final days
> dput(xFinaldays)
structure(list(Dataset = c("Lachnospiraceae", "Bifidobacteriaceae",
"Oscillospiraceae", "Enterobacteriaceae", "Erysipelotrichaceae",
"Clostridiaceae", "Acidaminococcaceae", "Peptostreptococcaceae",
"Sutterellaceae", "Bacteroidaceae", "Others"), Values = c(32106.33,
21813.1, 12246.03, 8259.62, 7029.33, 6365.3, 4091.83, 2610.92,
1968.89, 1864.72, 6713.37), per = c(30.56, 20.76, 11.66, 7.86,
6.69, 6.06, 3.89, 2.48, 1.87, 1.77, 6.39)), row.names = c(1L,
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 52L), class = "data.frame")
taxalen <- xFinaldays$Dataset[c(which(!(xFinaldays$Dataset %in% ColAssgn$taxa)))]
for (count in 1:length(taxalen)){
if(length(taxalen) > 0){
len = len +1
ColAssgn %>%
rbind(c(taxalen[count],allcols[len])) -> ColAssgn
}
}
xfindays <- function(){
xFinaldays %>%
ggplot(aes(x='',y=reorder(Values,Values),fill = Dataset))+
geom_bar(width=1,stat="identity")+
scale_fill_manual(breaks = ColAssgn$taxa,
values = ColAssgn$cols)+
theme_void()+
theme_classic() +
theme(legend.position = "top") +
coord_polar("y",start=0) +
theme(axis.line = element_blank())+
theme(axis.text = element_blank()) +
theme(axis.ticks = element_blank())+
labs(x = NULL, y = NULL, fill = NULL)+
ylab("End of Treatment")
}
xfindays()
And now for the combined group X plot :
group_x <- plot_grid(
xinidays() + theme(legend.position="none"),
xmiddays() + theme(legend.position="none"),
xfindays() + theme(legend.position="none"),
nrow = 1
)
group_x_plot <-plot_grid(group_x,ncol=1
,axis = "tblr"
,labels = "Genus level comparison at multiple treatment time points for Drug X",
label_size = 15
)
group_x_plot
Please anyone can help me with the above questions and fix this code?
many thanks,
Mitra

Related

How to replicate three plots next to each other with marginal plot on two of them?

This is what I want to achieve:
I'm trying to replicate the theme of these graph using ggplot, I searched online for articles and question to show me how to assign these plots the right size and position and also to assign the tight dot shape, and I found few articles that discussed changing position, I tried the following:
d1<-read.csv("./data/games.csv")
library(ggplot2)
library(dplyr)
d1 %>%
filter(winner != "draw") %>%
ggplot(aes(x=cream_rating, y=charcoal_rating, color = winner, shape = winner)) +
# Map winner on color. Add some transparency in case of overplotting
geom_point(alpha = 0.2, na.rm = TRUE) +
# Just a guess to add the cross: Add geom_pints with one variable fixed on its mean
# Should "draw"s be colored or dropped?
scale_color_manual(values = c(cream = "seagreen4", charcoal = "chocolate3")) +
scale_shape_manual(values = c(cream = 16, charcoal = 17)) +
ggtitle("Rating of Cream vs Charcoal") +
xlab("rating of cream") + ylab("rating of charcoal")+ theme_classic() + theme(plot.title = element_text(hjust = 0.5))
p.1<-ggplot(d1, aes(x=cream_rating, y=charcoal_rating)) +
# Map winner on color. Add some transparency in case of overplotting
geom_point(aes(color = winner), alpha = 0.2) +
# Add the cross: Add geom_pints with one variable fixed on its mean
geom_point(aes(y = mean(charcoal_rating), color = winner), alpha = 0.2) +
scale_shape_manual(values=c(16, 17)) +
# "draw"s should be dropped and removed from the title
scale_color_manual(values = c(cream = "seagreen4", charcoal = "chocolate3", draw = NA)) +
ggtitle("Rating of Cream vs Charcoal") +
xlab("rating of cream") + ylab("rating of charcoal") + theme_classic() + theme(plot.title = element_text(hjust = 0.5))
p.01<-ggplot(d1, aes(x=cream_rating, y=charcoal_rating)) +
# Map winner on color. Add some transparency in case of overplotting
geom_density2d(aes(color = winner), alpha = 0.2) +
# Add the cross: Add geom_pints with one variable fixed on its mean
scale_shape_manual(values=c(16, 17, 0)) +
# "draw"s should be dropped and removed from the title
scale_color_manual(values = c(cream = "seagreen4", charcoal = "chocolate3", draw = "blue")) +
ggtitle("Rating of Cream vs Charcoal") +
xlab("rating of cream") + ylab("rating of charcoal") + theme_classic() + theme(plot.title = element_text(hjust = 0.5))
plot.1<-p.1
plot.02<-ggExtra::ggMarginal(p.01, type = "density",
margins = 'both',
size = 5,
groupColour = TRUE,
groupFill = TRUE
)
plot.02
require(gridExtra)
plot.1<-p.1
plot.2<-ggExtra::ggMarginal(p.1, type = "histogram")
grid.arrange(plot.1, plot.2, ncol=3)
plot.02
library(cowplot)
theme_set(theme_cowplot())
plot.1<-p.1
plot.2<-ggExtra::ggMarginal(p.1, type = "histogram")
plot.02
plot_grid(plot.1, plot.2, plot.02, labels = "AUTO")
cowplot::plot_grid(plot.1, plot.2, plot.02, labels = "AUTO")
library(magrittr)
library(multipanelfigure)
figure1 <- multi_panel_figure(columns = 2, rows = 1, panel_label_type = "none")
# show the layout
figure1
figure1 %<>%
fill_panel(plot.1, column = 1, row = 1) %<>%
fill_panel(plot.2, column = 2, row = 1) %<>%
fill_panel(plot.02, column= 3, row = 1) %<>%
figure1
This is my data set structure:
structure(list(rated = c(FALSE, TRUE, TRUE, TRUE, TRUE, FALSE,
TRUE, FALSE, TRUE, TRUE), turns = c(13L, 16L, 61L, 61L, 95L,
5L, 33L, 9L, 66L, 119L), victory_status = structure(c(3L, 4L,
2L, 2L, 2L, 1L, 4L, 4L, 4L, 2L), .Label = c("draw", "mate", "outoftime",
"resign"), class = "factor"), winner = structure(c(2L, 1L, 2L,
2L, 2L, 3L, 2L, 1L, 1L, 2L), .Label = c("charcoal", "cream",
"draw"), class = "factor"), increment_code = structure(c(3L,
7L, 7L, 5L, 6L, 1L, 1L, 4L, 2L, 1L), .Label = c("10+0", "15+0",
"15+2", "15+30", "20+0", "30+3", "5+10"), class = "factor"),
cream_rating = c(1500L, 1322L, 1496L, 1439L, 1523L, 1250L,
1520L, 1413L, 1439L, 1381L), charcoal_rating = c(1191L, 1261L,
1500L, 1454L, 1469L, 1002L, 1423L, 2108L, 1392L, 1209L)), row.names = c(NA,
10L), class = "data.frame")
Thanks to #Stefan's suggestion (which was great help) in getting me this far.

How can I add vertical lines and horizontal text out of the plot axis limits in ggplot2/R?

I have a barplot made primarily in ggplot2. I want two vertical lines added and some text below the x-axis.
#Load data
d <- structure(list(author = structure(c(1L, 2L, 4L, 3L, 5L, 6L, 8L, 11L, 13L, 12L, 10L, 9L, 7L), .Label = c("Bahr et al", "Fuller et al", "Garbossa et al", "Gokhale et al", "Iuchi et al", "Lee et al", "Lee Y et all", "Merrel et al", "Newton et al", "Rossetti et al", "Usery et al", "Wychowski et al", "Zachenhofer et al"), class = "factor"), nAE = c(-22L, -34L, -158L, -90L, -70L, -41L, -48L, -32L, -73L, -23L, -25L, -13L, -46L), AE = c(3L, 1L, 7L, 1L, 3L, 10L, 3L, 6L, 3L, 5L, 4L, 6L, 5L), SAE = c(0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 2L, 0L, 2L, 0L, 0L)), .Names = c("author", "nAE", "AE", "SAE"), class = "data.frame", row.names = c(NA, -13L))
Code to my barplot:
library(dplyr)
library(tidyr)
library(ggplot2)
categories <- c("Adverse Effect", "No adverse effects", "Severe side effects")
cols <- c("#f6766d", "#01bfc4", "orange")
q <- d %>%
gather(key, value, -author) %>%
ggplot(aes(author, value, fill = key)) +
geom_col(alpha=0.9) +
scale_x_discrete(name="Author") +
scale_y_continuous(name="Number of observations", limits=c(-160,15),
seq(-160, 15, by=10)) +
theme_grey() +
theme(legend.position = "top") +
scale_fill_manual(labels = categories, values = cols) +
labs(fill = "")
I have attached a picture below of how I want my barplot to look like. As you can see, I have added two vertical lines (at random position) and three texts (in photoshop).
Thanks in advance,
C.
The vertical lines are no problem at all. Simply use:
+
geom_vline(xintercept= 3.5, colour = "red") +
geom_vline(xintercept= 10.5, colour = "red")
The values 3.5 and 10.5 mean that the lines intercept the x-axis between the third and fourth and respective between the tenth and eleventh author.
Adding text outside the plot is a whole different beast though. The "cleanest" way I could think of is adding the text inside the plot:
y <- min(d$nAE) + 10
textaes <- data.frame(y = c(y, y, y),
x = c(2, 7, 12),
lab = c("Text1", "Text2", "Text3"))
q <- d %>%
gather(key, value, -author) %>%
ggplot(aes(x=author, y=value, fill = key)) +
geom_col(alpha=0.9) +
scale_x_discrete(name="Author") +
scale_y_continuous(name="Number of observations", limits=c(-160,15),
seq(-160, 15, by=10), expand = c(0.15, 0.05)) +
theme_grey() +
theme(legend.position = "top",
axis.text.x = element_text(angle = 90, hjust = 1)) +
scale_fill_manual(labels = categories, values = cols) +
labs(fill = "") +
geom_vline(xintercept= 3.5, colour = "red") +
geom_vline(xintercept= 10.5, colour = "red") +
geom_text(mapping = aes(y = y, x = x, label = lab),
data = textaes, inherit.aes = FALSE)
q
EDIT: Just found a relatively easy way to add text outside the plot here. But I don't think it's a very nice solution:
q <- d %>%
gather(key, value, -author) %>%
ggplot(aes(x=author, y=value, fill = key)) +
geom_col(alpha=0.9) +
scale_x_discrete(name="Author") +
scale_y_continuous(name="Number of observations", limits=c(-160,15),
seq(-160, 15, by=10), expand = c(0.15, 0.05)) +
theme_grey() +
theme(legend.position = "top",
axis.text.x = element_text(angle = 90, hjust = 1)) +
scale_fill_manual(labels = categories, values = cols) +
labs(fill = "") +
geom_vline(xintercept= 3.5, colour = "red") +
geom_vline(xintercept= 10.5, colour = "red")
q
library(grid)
q
grid.text("Text1", x = unit(0.15, "npc"), y = unit(0.1, "npc"), gp=gpar(col="red"))
grid.text("Text2", x = unit(0.5, "npc"), y = unit(0.1, "npc"), gp=gpar(col="red"))
grid.text("Text3", x = unit(0.85, "npc"), y = unit(0.1, "npc"), gp=gpar(col="red"))
Will gridExtra package be of any help? It should deliver something close enough. You can combine 3 plots into 1 using method arrangeGrob or grid.arrange.
https://cran.r-project.org/web/packages/gridExtra/index.html

How to plot columns above and below data points in ggplot2

Using ggplot2, I am plotting percentage values for 15 species across three sites (each species occurs in each site). The data points associated with site 'C' are my reference points.
Now, instead of plotting sites 'A' and 'B' as points, I would like to display them using vertical lines or column-like structures. As such, these data points should be extended as vertical lines to the top or bottom side of the site 'C' points (green colour), i.e. to the top where values are larger than the reference value and bottom for smaller values.
Specifically, I would hope for a red line from a red point to the green point and a blue line from the blue point to the green point. The red line should ideally have the same width as the red point (and same for blue). The line should also be offset as are the red and blue points (relative to the green point), so that lines do not overlap. Finally, the line should not go to the center but the edge of a point.
For this purpose I have offset points for 'A' and 'B' and also reduced their size to half of the reference point size.
library(ggplot2)
MyData$species <- as.character(MyData$species)
MyData$species <- factor(MyData$species, levels=unique(MyData$species))
pos <- position_dodge(width=0.21)
cols <- c("C" = "darkgreen", "B" = "blue", "A" = "red")
tiff(file = "MyData.tiff", height=10, width=10, units="in", res=300, compression="lzw")
ggplot(data = MyData, aes(x=species, y=value, group=site, colour=site)) +
geom_point(data=subset(MyData, site=="C"), size = 4, shape=15, alpha=1, position=pos) +
geom_line(data=subset(MyData, site=="C"), size = 2, lwd=2, alpha=0.4, show_guide=FALSE) +
geom_point(data=subset(MyData, site!="C"), size = 1.8, shape=15, alpha=1, position = pos) +
scale_colour_manual(values = cols) +
xlab("Species") +
ylab("Value (%)") +
scale_y_continuous(expand=c(0.01,0.01),
limits=c(0.0,100),
breaks=c(0,20,40,60,80,100),
labels=c("0","20","40","60","80","100")) +
theme_bw() +
theme(legend.position="none") +
theme(axis.title.x = element_text(vjust=0.1,face="bold", size=16),
axis.text.x = element_text(vjust=0.4, size=14, angle=90, hjust=1.0)) +
theme(axis.title.y = element_text(vjust=0.1,face="bold", size=16),
axis.text.y = element_text(face="bold", size=14, angle=0)) +
theme(panel.grid.minor=element_blank(), panel.grid.major=element_blank()) +
theme(panel.border = element_rect(size=1, color = "black")) +
theme(plot.margin = unit(c(0.3,0.4,0.3,0.3),"lines"))
dev.off()
This is my current plot. So basically, I would like to replace the red and blue points with lines that extend to the green points (without overlapping them).
Many thanks in advance for any advice on an elegant solution for this.
This is a dput() of my dataset.
structure(list(site = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 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), .Label = c("A", "B", "C"), class = "factor"),
species = structure(c(13L, 11L, 2L, 14L, 1L, 9L, 12L, 10L,
6L, 8L, 15L, 7L, 3L, 4L, 5L, 13L, 11L, 2L, 14L, 1L, 9L, 12L,
10L, 6L, 8L, 15L, 7L, 3L, 4L, 5L, 13L, 11L, 2L, 14L, 1L,
9L, 12L, 10L, 6L, 8L, 15L, 7L, 3L, 4L, 5L), .Label = c("Species 1",
"Species 10", "Species 11", "Species 12", "Species 13", "Species 14",
"Species 15", "Species 2", "Species 3", "Species 4", "Species 5",
"Species 6", "Species 7", "Species 8", "Species 9"), class = "factor"),
value = c(2, 3.25, 3.53, 4.31, 4.59, 5.26, 6.02, 6.42, 6.6,
7.26, 8.89, 12.45, 35.62, 72.42, 73.55, 1.36, 2.36, 2.17,
10.34, 6.84, 1.88, 5.09, 7.35, 3.87, 10.55, 6.6, 14.64, 39.57,
88.06, 64.54, 5.03, 12.34, 5.42, 3.63, 5.16, 6.04, 3, 8.94,
3.28, 7.64, 6.25, 21.96, 39.35, 78.55, 47.35)), .Names = c("site",
"species", "value"), class = "data.frame", row.names = c(NA,
-45L))
You can try geom_linerange() for the lines from points A/B to point C.
Define the ymin/ymax values for each site/species, & reorder site such that A / B lines drop down to each side of point C:
library(dplyr)
MyData <- MyData %>%
group_by(species) %>%
mutate(value.C = value[site == "C"]) %>%
rowwise() %>%
mutate(value.min = min(value, value.C),
value.max = max(value, value.C)) %>%
ungroup() %>%
mutate(site = factor(site, levels = c("A", "C", "B")))
Plot:
# vary dodge width such that the lines drop to the edge of point C
# for your chosen dimensions (for mine 0.5 was about right)
pos <- position_dodge(width = 0.5)
ggplot(data = MyData,
aes(x = species, y = value,
ymin = value.min, ymax = value.max,
group = site, colour = site, size = site)) +
geom_linerange(size = 1.8, alpha = 0.4, position = pos) +
geom_line(data = subset(MyData, site == "C"),
size = 2, lwd = 2, alpha = 0.4) +
geom_point(data = subset(MyData, site == "C"),
size = 4, shape = 15, position = pos) +
scale_color_manual(values = cols) +
theme_classic() +
theme(legend.position = "none")
# + other theme-related settings...
You can add geom_line to draw the vertical lines
library(ggplot2)
MyData$species <- as.character(MyData$species)
MyData$species <- factor(MyData$species, levels=unique(MyData$species))
pos <- position_dodge(width=0.21)
cols <- c("C" = "darkgreen", "B" = "blue", "A" = "red")
windows()
ggplot(data = MyData, aes(x=species, y=value, group=site, colour=site)) +
geom_point(data=subset(MyData, site=="C"), size = 4, shape=15, alpha=1, position=pos) +
geom_line(data=subset(MyData, site=="C"), size = 2, lwd=2, alpha=0.4, show_guide=FALSE) +
geom_point(data=subset(MyData, site!="C"), size = 1.8, shape=15, alpha=1, position = pos) +
geom_line(aes(group = species)) + #New code Added
scale_colour_manual(values = cols) +
xlab("Species") +
ylab("Value (%)") +
scale_y_continuous(expand=c(0.01,0.01),
limits=c(0.0,100),
breaks=c(0,20,40,60,80,100),
labels=c("0","20","40","60","80","100")) +
theme_bw() +
theme(legend.position="none") +
theme(axis.title.x = element_text(vjust=0.1,face="bold", size=16),
axis.text.x = element_text(vjust=0.4, size=14, angle=90, hjust=1.0)) +
theme(axis.title.y = element_text(vjust=0.1,face="bold", size=16),
axis.text.y = element_text(face="bold", size=14, angle=0)) +
theme(panel.grid.minor=element_blank(), panel.grid.major=element_blank()) +
theme(panel.border = element_rect(size=1, color = "black")) +
theme(plot.margin = unit(c(0.3,0.4,0.3,0.3),"lines"))

How do I change the colour of an outline in a ggplot bubble plot?

I am putting together a bubble chart in ggplot2, and want to change the outline of my bubbles (to comply with work's formatting guidelines). My problem is that I'm using colors to group variables, and I'm using a custom palette (again, for work). Ideally, I'd like to put black borders on the bubbles.
Here's my data-frame:
mmur <- structure(list(Medgrowth = c(-1.02232983588915, 3.01155115511551,-0.220617729642996, 1.96506550218342, 0.943970767356888, 0.810810810810807,0.0166694449074782, 0.21064457239153, 0.0876731544801004, 0.132216835610393,0.370644922164558,0.23378141437756, 1.27810650887574, 0.42301184433164,0.394880174291941, 0.54216172568924, 1.32690882134916, 0.499722376457527,-0.108885017421599), Medunemp = c(4.430550475, 2.5060469975,4.1239796475, 2.0585977455, 3.846659243, 3.1792594425, 4.0033450105,6.0882984255, 3.091889808,3.7462810695, 2.4038147815, 3.0065393475,2.3331894185, 4.9482480125, 2.0955470885, 1.616694725, 1.873037069,3.060170157, 3.0131425595), Empsize = c(324.2,270.6, 962.1,149, 962.4, 421.1, 1197.8, 777.8, 552.8, 234.8, 421.1, 203.2,915.7, 396.1, 685.9, 904.5, 1366.9, 215.4, 440.5), Eduratio = c(0.1,0.2, 0.1, 0.2, 0.1, 0.2, 0.1, 0.1, 0.1, 0.3, 0.3, 0.2, 0.5, 0.2,0.3, 0.6, 0.4, 0.2, 0.1), Names = structure(c(3L, 12L, 11L, 7L,5L, 19L, 17L, 1L, 18L, 10L, 8L, 16L, 14L, 2L, 15L, 6L, 9L, 4L,13L), .Label = c("Accom", "Admin","Agric", "Arts.", "Const","Educa", "Elect", "Finan", "Healt","Infor","Manuf","Minin","Other", "Profe", "Publi", "Renta", "Retai", "Trans", "Whole"), class = "factor"), colour1 = structure(c(6L, 5L, 6L, 5L, 6L,5L, 6L, 6L, 6L, 4L, 4L, 5L, 2L, 5L, 4L, 1L, 3L, 5L, 6L), .Label = c("#8C2D04","#CC4C02", "#EC7014", "#FE9929","#FEC44F", "#FEE391"), class = "factor")), .Names = c("Medgrowth","Medunemp", "Empsize", "Eduratio", "Names", "colour1"), row.names = c("Agric","Minin", "Manuf", "Elect", "Const", "Whole", "Retai", "Accom","Trans", "Infor", "Finan", "Renta", "Profe", "Admin", "Publi","Educa", "Healt", "Arts.", "Other"), class = "data.frame")
And here's my plot code:
bbubc1 <- ggplot(mmur, aes(x = Medgrowth, y = Medunemp, size = Empsize, label = Names, colour = colour1)) +
geom_point() +
scale_size(range = c(5, sqrt(max(mmur$Empsize)/min(mmur$Empsize)*5^2)), name = "Employment in\n2012 (thousands)") +
geom_text(size = 4, colour = "black", vjust = -1) +
scale_colour_manual(values = levels(mmur$colour1), name = "Per cent with\ntertiary degree", label = c(60, 50, 40, 30, 20, 10)) +
xlab("Median employment growth rate 2001 - 2012") +
ylab("Median unemployment rate 2001 - 2012") +
opts(axis.text.x=theme_text(angle=0, hjust=0, size = 16)) +
opts(axis.text.y=theme_text(angle=0, hjust=0, size = 16)) +
opts(axis.title.x=theme_text(size = 16)) +
opts(legend.title = theme_text(size = 16)) +
opts(axis.title.y=theme_text(size = 16, angle = 90)) +
geom_vline(colour = I("grey")) +
geom_hline(colour = I("grey")) +
ylim(c(0,7))
The plot is here:
Some of R's plotting characters allow both an internal fill and an edge colour, so using one of these shapes to draw your points, and replacing your colour aesthetics with fill, should do the job:
ggplot(mmur, aes(x = Medgrowth, y = Medunemp, size = Empsize, label = Names, fill = colour1)) +
geom_point(shape=21, colour='black') +
scale_size(range = c(5, sqrt(max(mmur$Empsize)/min(mmur$Empsize)*5^2)), name = "Employment in\n2012 (thousands)") +
geom_text(size = 4, colour = "black", vjust = -1) +
scale_fill_manual(values = levels(mmur$colour1), name = "Per cent with\ntertiary degree", label = c(60, 50, 40, 30, 20, 10)) +
xlab("Median employment growth rate 2001 - 2012") +
ylab("Median unemployment rate 2001 - 2012") +
opts(axis.text.x=theme_text(angle=0, hjust=0, size = 16)) +
opts(axis.text.y=theme_text(angle=0, hjust=0, size = 16)) +
opts(axis.title.x=theme_text(size = 16)) +
opts(legend.title = theme_text(size = 16)) +
opts(axis.title.y=theme_text(size = 16, angle = 90)) +
geom_vline(colour = I("grey")) +
geom_hline(colour = I("grey")) +
ylim(c(0,7))
Run example(points) and go to the third plot to see which shapes can be filled like this, i.e. shapes 21:25.

ggplot2 dotplot with facet_grid with labels on top ala facet_wrap (but w/ space = "free_x")?

I really like how my dotplot looks with facet_wrap (facet labels on top) but I'd ideally like to be able to pass it a space = "free_x" so the facets are sized appropriately. The problem with facet_grid is that the facet labels move to the side of the plot, which in this case doesn't work well because I want each panel to be separated.
Code follows:
# load data
plotdat <- structure(list(level = c("Lost (N =328)", "Won (N =75)", "Lost (N =10)",
"Won (N =65)", "Challenger (N =318)", "Incumbent (N =85)", "Arab (N =7)",
"Black (N =222)", "East Asian (N =40)", "Latino (N =107)", "Other (N =10)",
"South Asian (N =17)", "Not (N =252)", "Statewide (N =151)"),
mean = c(0.59834264517378, 0.645308353066667, 0.6382179387,
0.646399186046154, 0.595756747751572, 0.649457274258823,
0.682776774142857, 0.557334915725225, 0.6654738063, 0.68260777364486,
0.6061308922, 0.613378378411765, 0.616298597519841, 0.591703758423841
), se = c(0.00597842210656315, 0.0113080614816089, 0.044927778673023,
0.011274258338002, 0.00622316181664198, 0.00900474213888581,
0.0247451786416615, 0.00690804451732034, 0.0116899960061005,
0.00777478853477299, 0.0183766282892234, 0.0166464474073244,
0.00669527297092827, 0.00887170639612841), N = c(328L, 75L,
10L, 65L, 318L, 85L, 7L, 222L, 40L, 107L, 10L, 17L, 252L,
151L), var = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L,
4L, 4L, 4L, 4L, 5L, 5L), .Label = c("Primary Election", "General Election",
"Incumbency", "Race", "Statewide District"), class = "factor")), .Names = c("level",
"mean", "se", "N", "var"), row.names = c(NA, 14L), class = "data.frame")
library('ggplot2')
# with facet_wrap:
ggplot(plotdat, aes(x = mean, xmin = mean-se, xmax = mean+se, y = level)) +
geom_point() + geom_segment( aes(x = mean-se, xend = mean+se,
y = level, yend=level)) +
facet_wrap(~var, ncol=1, scales = "free_y") +
theme_bw() + opts(axis.title.x = theme_text(size = 12, vjust = .25))+
xlab("Mean V (Brightness) for Candidate's Face") + ylab("") +
opts(title = expression("Skin Complexion for 2010 Minority Candidates"))
# with facet_grid:
ggplot(plotdat, aes(x = mean, xmin = mean-se, xmax = mean+se, y = level)) +
geom_point() + geom_segment( aes(x = mean-se, xend = mean+se,
y = level, yend=level)) +
facet_grid(var~., scales = "free_y", space = "free_y") +
theme_bw() + opts(axis.title.x = theme_text(size = 12, vjust = .25))+
xlab("Mean V (Brightness) for Candidate's Face") + ylab("") +
opts(title = expression("Skin Complexion for 2010 Minority Candidates"))
Any suggestions? Thanks very much!
Update Using the ggplot grob, this is fairly easy to do. See here or here
ggplot grob version
library(ggplot2)
library(dplyr)
library(grid)
# Get the plot; plotdat data frame is below
p = ggplot(plotdat, aes(x = mean, xmin = mean-se, xmax = mean+se, y = level)) +
geom_point() + geom_segment( aes(x = mean-se, xend = mean+se,
y = level, yend=level)) +
facet_wrap(~var, ncol=1, scales = "free_y") +
theme_bw() + theme(axis.title.x = element_text(size = 12, vjust = .25))+
xlab("Mean V (Brightness) for Candidate's Face") + ylab("") +
ggtitle("Skin Complexion for 2010 Minority Candidates")
# From 'plotdat', get the number of 'levels' for each 'var'.
# That is, the number y-breaks in each panel.
N <- plotdat %>% group_by(var) %>%
summarise(count = n()) %>%
`[[`(2)
# Get the ggplot grob
gt = ggplotGrob(p)
# Get the locations of the panels in the gtable layout.
panels <- gt$layout$t[grepl("panel", gt$layout$name)]
# Replace the default panel heights with relative heights
gt$heights[panels] <- unit(N, "null")
## Draw gt
grid.newpage()
grid.draw(gt)
Original answer
EDIT: Updated to ggplot2 version 0.9.3.1
This is not going to answer your question. It tweaks the facet_grid look.
I'm not sure what you mean by "each panel being separated". If you are concerned that the strip text in the facet_grid plot extends beyond the boundaries of the strip, the text can be rotated using theme(strip.text.y = element_text(angle = 0)). Furthermore, the text can be made to wrap round to multiple lines using str_wrap from the stingr package.
# load data
plotdat <- structure(list(level = c("Lost (N =328)", "Won (N =75)", "Lost (N =10)",
"Won (N =65)", "Challenger (N =318)", "Incumbent (N =85)", "Arab (N =7)",
"Black (N =222)", "East Asian (N =40)", "Latino (N =107)", "Other (N =10)",
"South Asian (N =17)", "Not (N =252)", "Statewide (N =151)"),
mean = c(0.59834264517378, 0.645308353066667, 0.6382179387,
0.646399186046154, 0.595756747751572, 0.649457274258823,
0.682776774142857, 0.557334915725225, 0.6654738063, 0.68260777364486,
0.6061308922, 0.613378378411765, 0.616298597519841, 0.591703758423841
), se = c(0.00597842210656315, 0.0113080614816089, 0.044927778673023,
0.011274258338002, 0.00622316181664198, 0.00900474213888581,
0.0247451786416615, 0.00690804451732034, 0.0116899960061005,
0.00777478853477299, 0.0183766282892234, 0.0166464474073244,
0.00669527297092827, 0.00887170639612841), N = c(328L, 75L,
10L, 65L, 318L, 85L, 7L, 222L, 40L, 107L, 10L, 17L, 252L,
151L), var = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L,
4L, 4L, 4L, 4L, 5L, 5L), .Label = c("Primary Election", "General Election",
"Incumbency", "Race", "Statewide District"), class = "factor")), .Names = c("level",
"mean", "se", "N", "var"), row.names = c(NA, 14L), class = "data.frame")
library('ggplot2')
library(stringr)
plotdat$var = str_wrap(plotdat$var, width = 10)
# with facet_grid:
ggplot(plotdat, aes(x = mean, xmin = mean-se, xmax = mean+se, y = level)) +
geom_point() + geom_segment( aes(x = mean-se, xend = mean+se,
y = level, yend=level)) +
facet_grid(var~., scales = "free_y", space = "free_y") +
theme_bw() +
ggtitle("Skin Complexion for 2010 Minority Candidates") +
xlab("Mean V (Brightness) for Candidate's Face") + ylab("") +
theme(axis.title.x = element_text(size = 12, vjust = .25),
strip.text.y = element_text(angle = 0))
If "panels to be separated" means "additional space between the panels", use theme(panel.margin = unit(2, "line"), after loading grid.
library(grid)
ggplot(plotdat, aes(x = mean, xmin = mean-se, xmax = mean+se, y = level)) +
geom_point() + geom_segment( aes(x = mean-se, xend = mean+se,
y = level, yend=level)) +
facet_grid(var~., scales = "free_y", space = "free_y") +
theme_bw() +
ggtitle("Skin Complexion for 2010 Minority Candidates") +
xlab("Mean V (Brightness) for Candidate's Face") + ylab("") +
theme(axis.title.x = element_text(size = 12, vjust = .25),
strip.text.y = element_text(angle = 0),
panel.margin = unit(2, "lines"))

Resources