Scaling data to secondary axis in R (ggplot2) - r

I'm trying to build a line chart with ggplot2 in which I would like to have 2 lines, each adapted to a different axis. I'm trying the following code (where df4 is my data frame):
p1 = ggplot(df4, mapping = aes(x=taxon, y=cov, group = 1, colour = "Coverage", xlab("Cover"))) +
geom_line() +
labs (x = "Taxon", y = "Coverage") +
geom_line(aes(y=depth, colour = "Depth")) +
theme(axis.text.x = element_text(angle = 75, hjust= 1, vjust = 1)) +
scale_colour_manual(values = c("navyblue", "green4")) +
scale_y_continuous(sec.axis = sec_axis(~./4, name = "Depth"))
With this, I am able to build a chart with 2 y-axis and 2 lines, but both lines are adapted to the primary y-axis (the secondary axis is there, but it's useless). Is there maybe a parameter with which I can ask my data to follow this axis?
Blue line values only go until 1, so they should be adapted to the secondary axis
This is an example of my data:
structure(list(taxon = structure(c(80L, 57L, 74L, 32L, 1L, 3L,
41L, 9L, 70L, 12L), .Label = c("c__Tremellomycetes", "f__Listeriaceae",
"f__Saccharomycetaceae", "g__Escherichia", "g__Klebsiella", "g__Pseudomonas",
"g__Saccharomyces", "g__Salmonella", "g__Staphylococcus", "s__Bacillus_amyloliquefaciens",
"s__Bacillus_phage_phi105", "s__Bacillus_siamensis", "s__Bacillus_sp_JS",
"s__Bacillus_subtilis", "s__Bacillus_vallismortis", "s__Citrobacter_sp_30_2",
"s__Cronobacter_phage_ENT47670", "s__Enterobacter_cancerogenus",
"s__Enterobacteria_phage_BP_4795", "s__Enterobacteria_phage_cdtI",
"s__Enterobacteria_phage_ES18", "s__Enterobacteria_phage_fiAA91_ss",
"s__Enterobacteria_phage_HK629", "s__Enterobacteria_phage_IME10",
"s__Enterobacteria_phage_lambda", "s__Enterobacteria_phage_mEp237",
"s__Enterobacteria_phage_mEp460", "s__Enterobacteria_phage_Min27",
"s__Enterobacteria_phage_P22", "s__Enterobacteria_phage_YYZ_2008",
"s__Enterococcus_faecalis", "s__Enterococcus_gilvus", "s__Enterococcus_phage_phiEf11",
"s__Enterococcus_phage_phiFL1A", "s__Enterococcus_phage_phiFL3A",
"s__Escherichia_coli", "s__Escherichia_phage_HK639", "s__Escherichia_phage_P13374",
"s__Lactobacillus_fermentum", "s__Listeria_innocua", "s__Listeria_ivanovii",
"s__Listeria_marthii", "s__Listeria_monocytogenes", "s__Listeria_phage_2389",
"s__Listeria_phage_A118", "s__Listeria_phage_A500", "s__Paenibacillus_sp_ICGEB2008",
"s__Phage_Gifsy_1", "s__Phage_Gifsy_2", "s__Pseudomonas_aeruginosa",
"s__Pseudomonas_mendocina", "s__Pseudomonas_phage_B3", "s__Pseudomonas_phage_D3",
"s__Pseudomonas_phage_DMS3", "s__Pseudomonas_phage_F10", "s__Pseudomonas_phage_F116",
"s__Pseudomonas_phage_PAJU2", "s__Pseudomonas_phage_Pf1", "s__Pseudomonas_phage_phi297",
"s__Pseudomonas_sp_2_1_26", "s__Pseudomonas_sp_P179", "s__Salmonella_enterica",
"s__Salmonella_phage_Fels_1", "s__Salmonella_phage_Fels_2", "s__Salmonella_phage_SETP13",
"s__Salmonella_phage_ST64B", "s__Shigella_phage_Sf6", "s__Staphylococcus_aureus",
"s__Staphylococcus_phage_42E", "s__Staphylococcus_phage_55",
"s__Staphylococcus_phage_80alpha", "s__Staphylococcus_phage_P954",
"s__Staphylococcus_phage_phi2958PVL", "s__Staphylococcus_phage_phiMR25",
"s__Staphylococcus_phage_phiN315", "s__Staphylococcus_phage_phiNM3",
"s__Staphylococcus_phage_phiPVL_CN125", "s__Staphylococcus_phage_phiPVL108",
"s__Staphylococcus_phage_PT1028", "s__Staphylococcus_phage_StauST398_1",
"s__Staphylococcus_phage_StauST398_3", "s__Staphylococcus_prophage_phiPV83",
"s__Stx2_converting_phage_1717", "s__Stx2_converting_phage_86"
), class = "factor"), cov = c(0.987654320987654, 0.99685534591195,
0.994535519125683, 0.147003745318352, 0.390923694779116, 0.92831541218638,
0.99079754601227, 0.993055555555556, 0.497512437810945, 0.58144695960941
), depth = c(1.68148148148148, 0.99685534591195, 0.994535519125683,
0.147003745318352, 0.390923694779116, 0.92831541218638, 0.99079754601227,
1.34722222222222, 0.497512437810945, 0.58144695960941)), .Names = c("taxon",
"cov", "depth"), row.names = c(40L, 10L, 58L, 44L, 7L, 55L, 29L,
13L, 2L, 53L), class = "data.frame")

You just need to multiply the 'depth' geom_line with 4 :
ggplot(df4, mapping = aes(x=taxon, y=cov, group = 1, colour = "Coverage", xlab("Cover"))) +
geom_line() +
labs (x = "Taxon", y = "Coverage") +
geom_line(aes(y=depth * 4, colour = "Depth")) +
theme(axis.text.x = element_text(angle = 75, hjust= 1, vjust = 1)) +
scale_colour_manual(values = c("navyblue", "green4")) +
scale_y_continuous(sec.axis = sec_axis(~./4, name = "Depth"))

Related

How to implement stacked bar graph with a line chart in R

I have a dataset containing y variable as Year and x variables as (A, B, C(%)). I have attached the dataset here.
dput(result)
structure(list(Year = 2008:2021, A = c(4L, 22L, 31L, 48L, 54L,
61L, 49L, 56L, 59L, 85L, 72L, 58L, 92L, 89L), B = c(1L, 2L, 6L,
7L, 14L, 21L, 15L, 27L, 27L, 46L, 41L, 26L, 51L, 62L), C... = c(25,
9.09, 19.35, 14.58, 25.93, 34.43, 30.61, 48.21, 45.76, 54.12,
56.94, 44.83, 55.43, 69.66)), class = "data.frame", row.names = c(NA,
-14L))
The variables A and B will be plotted as stacked bar graph and the C will be plotted as line chart in the same plot. I have generated the plot using excel like below:
How can I create the same plot in R?
You first need to reshape longer, for example with pivot_longer() from tidyr, and then you can use ggplot2 to plot the bars and the line in two separate layers. The fill = argument in the geom_bar(aes()) lets you stratify each bar according to a categorical variable - name is created automatically by pivot_longer().
library(ggplot2)
library(tidyr)
dat |>
pivot_longer(A:B) |>
ggplot(aes(x = Year)) +
geom_bar(stat = "identity", aes(y = value, fill = name)) +
geom_line(aes(y = `C(%)`), size = 2)
Created on 2022-06-09 by the reprex package (v2.0.1)
You're asking for overlaid bars, in which case there's no need to pivot, and you can add separate layers. However I would argue that this could confuse or mislead many people - usually in stacked plots bars are stacked, not overlaid, so thread with caution!
library(ggplot2)
library(tidyr)
dat |>
ggplot(aes(x = Year)) +
geom_bar(stat = "identity", aes(y = A), fill = "lightgreen") +
geom_bar(stat = "identity", aes(y = B), fill = "red", alpha = 0.5) +
geom_line(aes(y = `C(%)`), size = 2) +
labs(y = "", caption = "NB: bars are overlaid, not stacked!")
Created on 2022-06-09 by the reprex package (v2.0.1)
I propose this:
library(data.table)
library(ggplot2)
library(ggthemes)
dt <- fread("dataset.csv")
dt.long <- melt(dt, id.vars = c("Year"))
dt.AB <- dt.long[variable %in% c("A", "B"), ]
dt.C <- copy(dt.long[variable == "C(%)", .(Year, variable, value = value * 3/2)])
ggplot(dt.AB, aes(x = Year, y = value, fill = variable), ) +
geom_bar(stat = "identity") +
geom_line(data=dt.C, colour='red', aes(x = Year, y = value)) +
scale_x_continuous(breaks = pretty(dt.AB$Year,
n = length(unique(dt.AB$Year)))) +
scale_y_continuous(
name = "A&B",
breaks = seq (0, 150, 10),
sec.axis = sec_axis(~.*2/3, name="C(%)", breaks = seq (0, 100, 10))
) + theme_hc() +
scale_fill_manual(values=c("grey70", "grey50", "grey30")) +
theme(
axis.line.y = element_line(colour = 'black', size=0.5,
linetype='solid'))

Overlaying line plot on barplot ggplot -

I am trying to overlay a line plot onto a barplot. I can plot both separately :
##plot sites
ggplot(graph, aes(x = Month, y = Anopheles_pos))
+ geom_col(size = 1, color = "darkblue", fill = "white")
##plot line
ggplot(graph, aes(x = Month, y = Mean_EVI)) +
geom_line(size = 1.5, color = "blue", group = 1)
However when I try to plot the line onto the barplot, it is a flat line at the bottom. I tried to deal with the issue by fixing the second y axis (on the right) to be the same scale as the line, but this has not fixed how the line plots.
##plot together
ggplot(graph) +
geom_col(aes( x = factor(Month, levels = month.name), y = Anopheles_pos), size = 1,
color = "darkblue", fill = "white") +
geom_line(aes(x = factor(Month, levels = month.name), y = Mean_EVI), size = 1.5,
color = "red", group = 1) +
scale_y_continuous(sec.axis = sec_axis(~./50, name = "Mean_EVI"))
One small other issue is I can't figure out how to make the x axis 0-100 as the Anopheles_pos values are percentages.
Thanks in advance!!
DATA:
Mean_EVI : c(0.5687068, 0.5663895, 0.5653846, 0.6504931, 0.584727, 0.5799395,
0.617363, 0.581645, 0.6190386, 0.5208025, 0.6097692, 0.5689)
Anopheles_pos : c(33L, 42L, 38L, 31L, 54L, 47L, 22L, 15L, 2L, 15L, 12L, 19L)
You need to scale up your Mean_EVI values by 50 to match the ./50 part of your sec.axis call.
Mean_EVI <- c(0.6190386, 0.5208025, 0.6097692, 0.5689, 0.5687068, 0.5663895, 0.5653846, 0.6504931, 0.584727, 0.5799395, 0.617363, 0.581645)
Anopheles_pos <- c(2L, 15L, 12L, 19L, 33L, 42L, 38L, 31L, 54L, 47L, 22L, 15L)
graph <- data.frame(Mean_EVI, Anopheles_pos, Month = 1:12)
ggplot(graph) +
geom_col(aes(x = factor(Month, labels = month.name), y = Anopheles_pos), size = 1,
color = "darkblue", fill = "white") +
geom_line(aes(x = factor(Month, labels = month.name), y = Mean_EVI*50), size = 1.5,
color = "red", group = 1) +
scale_y_continuous(sec.axis = sec_axis(~./50, name = "Mean_EVI")) +
coord_cartesian(ylim = c(0, 100))

How to automatically adjust the width of each facet for facet_wrap?

I want to plot a boxplot using ggplot2, and i have more than one facet, each facet has different terms, as follows:
library(ggplot2)
p <- ggplot(
data=Data,
aes(x=trait,y=mean)
)
p <- p+facet_wrap(~SP,scales="free",nrow=1)
p <- p+geom_boxplot(aes(fill = Ref,
lower = mean - sd,
upper = mean + sd,
middle = mean,
ymin = min,
ymax = max,
width=c(rep(0.8/3,3),rep(0.8,9))),
lwd=0.5,
stat="identity")
as showed, the width of box in different facet is not the same, is there any way to adjust all the box at a same scale? I had tried to use facet_grid, it can automatically change the width of facets, but all facets share the same y axis.
Data
Data <- structure(list(SP = structure(c(3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L,
4L, 4L, 4L, 4L), .Label = c("Human", "Cattle", "Horse", "Maize"
), class = "factor"), Ref = structure(c(3L, 2L, 1L, 3L, 3L, 3L,
2L, 2L, 2L, 1L, 1L, 1L), .Label = c("LMM", "Half", "Adoptive"
), class = "factor"), trait = structure(c(11L, 11L, 11L, 14L,
13L, 12L, 14L, 13L, 12L, 14L, 13L, 12L), .Label = c("cad", "ht",
"t2d", "bd", "cd", "ra", "t1d", "fpro", "mkg", "scs", "coat colour",
"ywk", "ssk", "gdd"), class = "factor"), min = c(0.324122039,
0.336486555, 0.073152049, 0.895455441, 0.849944623, 0.825248005,
0.890413591, 0.852385351, 0.826470308, 0.889139116, 0.838256672,
0.723753592), max = c(0.665536838, 0.678764774, 0.34033228, 0.919794865,
0.955018001, 0.899903826, 0.913350912, 0.957305688, 0.89843716,
0.911257005, 0.955312678, 0.817489555), mean = c(0.4919168555,
0.5360103372, 0.24320509565, 0.907436221, 0.9057516121, 0.8552899502,
0.9035394117, 0.9068819173, 0.8572309823, 0.90125638965, 0.90217769835,
0.7667208778), sd = c(0.0790133656517775, 0.09704320004497, 0.0767552215753863,
0.00611921020505611, 0.0339614482273291, 0.0199389195311925,
0.00598633573504195, 0.0332634006653858, 0.0196465508521771,
0.00592476494699222, 0.0348144156099722, 0.0271827880539459)), .Names = c("SP",
"Ref", "trait", "min", "max", "mean", "sd"), class = "data.frame", row.names = c(10L,
11L, 12L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L))
While u/z-lin's answer works, there is a far simpler solution. Switch from facet_wrap(...) to use facet_grid(...). With facet_grid, you don't need to specify rows and columns. You are still able to specify scales= (which allows automatic adjustment of axis scales for each facet if wanted), but you can also specify space=, which does the same thing, but with the scaling of the overall facet width. This is what you want. Your function call is now something like this:
ggplot(Data, aes(x = trait, y = mean)) +
geom_boxplot(aes(
fill = Ref, lower = mean-sd, upper = mean+sd, middle = mean,
ymin = min, ymax = max),
lwd = 0.5, stat = "identity") +
facet_grid(. ~ SP, scales = "free", space='free') +
scale_x_discrete(expand = c(0, 0.5)) +
theme_bw()
Some more description of layout of facets can be found here.
As #cdtip mentioned, this does not allow for independent y scales for each facet, which is what the OP asked for initially. Luckily, there is also a simple solution for this, which utilizes facet_row() from the ggforce package:
library(ggforce)
# same as above without facet_grid call..
p <- ggplot(Data, aes(x = trait, y = mean)) +
geom_boxplot(aes(
fill = Ref, lower = mean-sd, upper = mean+sd, middle = mean,
ymin = min, ymax = max),
lwd = 0.5, stat = "identity") +
scale_x_discrete(expand = c(0, 0.5)) +
theme_bw()
p + ggforce::facet_row(vars(SP), scales = 'free', space = 'free')
You can adjust facet widths after converting the ggplot object to a grob:
# create ggplot object (no need to manipulate boxplot width here.
# we'll adjust the facet width directly later)
p <- ggplot(Data,
aes(x = trait, y = mean)) +
geom_boxplot(aes(fill = Ref,
lower = mean - sd,
upper = mean + sd,
middle = mean,
ymin = min,
ymax = max),
lwd = 0.5,
stat = "identity") +
facet_wrap(~ SP, scales = "free", nrow = 1) +
scale_x_discrete(expand = c(0, 0.5)) + # change additive expansion from default 0.6 to 0.5
theme_bw()
# convert ggplot object to grob object
gp <- ggplotGrob(p)
# optional: take a look at the grob object's layout
gtable::gtable_show_layout(gp)
# get gtable columns corresponding to the facets (5 & 9, in this case)
facet.columns <- gp$layout$l[grepl("panel", gp$layout$name)]
# get the number of unique x-axis values per facet (1 & 3, in this case)
x.var <- sapply(ggplot_build(p)$layout$panel_scales_x,
function(l) length(l$range$range))
# change the relative widths of the facet columns based on
# how many unique x-axis values are in each facet
gp$widths[facet.columns] <- gp$widths[facet.columns] * x.var
# plot result
grid::grid.draw(gp)
In general, you can determine the width of a box plot in ggplot like so:
ggplot(data= df, aes(x = `some x`, y = `some y`)) + geom_boxplot(width = `some witdth`)
In your case, you might consider setting the width of all the box plots to the range of x divided by the maximum number of elements (in the leftmost figure).

Unable to customize legend in ggplot

I am plotting yearly demand using ggplot (my code below) but I am not able to put color legend for the plot. My data.frame has "Zone" and "TotalDemand" (only 2 columns) and I have three data.frames for three years ("sales12", "sales13" and "sales14").
ggplot() +
geom_point(data=sales12, aes(x=factor(Zone), y=TotalDemand/1000),
color='green',size=6, shape=17) +
geom_point(data=sales13, aes(x=factor(Zone), y=TotalDemand/1000),
color='red',size=6, shape=18)+
geom_point(data=sales14, aes(x=factor(Zone), y=TotalDemand/1000),
color='black',size=4, shape=19) +
labs(y='Demand (in 1000s)',x='Zones') +
scale_colour_manual(name = 'the colour',
values = c('green'='green', 'black'='black', 'red'='red'),
labels = c('12','13','14'))
Please help me to identify my mistake.
With a very small example data frame, df, I melted it to format it for ggplot.
dput(df)
structure(list(Zone = structure(1:4, .Label = c("Alpha", "Baker",
"Charlie", "Delta"), class = "factor"), TotalDemand = c(90L,
180L, 57L, 159L), sales12 = c(25L, 40L, 13L, 50L), sales13 = c(30L,
60L, 16L, 55L), sales14 = c(35L, 80L, 28L, 54L)), .Names = c("Zone",
"TotalDemand", "sales12", "sales13", "sales14"), class = "data.frame", row.names = c(NA,
-4L))
df.m <- melt(df, id.vars = "Zone", measure.vars = c("sales12", "sales13", "sales14"))
ggplot(df.m, aes(x=factor(Zone), y=value, color = variable )) +
geom_point(size=6, shape=17) +
labs(y='Demand (in 1000s)',x='Zones') +
scale_colour_manual(values = c('green', 'black', 'red'))
You can adjust size and shape and colors of your points, add a title, etc.. Your legend can also be positioned on the bottom, for example.

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