I'm running in a bit of a problem plotting some data with ggplot2: I want to use a facet_wrap over a variable AdultInputProp, but R doesn't find the variable and instead returns an Error in as.quoted(facets) : object 'AdultInputProp' not found. Now I understand that this simply means that R can't find this variable in the dataset used to plot, but if I ask ggplot2 to instead use the same variable for to create a shape scale, it works just fine. Any idea what the problem might be?
Sorry, I'm not too sure how to make a minimal working example with a generated df from scratch, so here's the df I'm using, and the code bellow. I've also tried using facet_grid instead of facet_wrap but ran into the same problem.
The code here with facets returns the above-mentioned error:
df.plot.GBPperAIP <- ggplot(df.sum.GBPperAIP,
aes(x=TestIteration, y=Error,
colour=GoalBabblingProp,
group=interaction(GoalBabblingProp,
AdultInputProp))) +
facet_wrap(AdultInputProp) +
xlab("Step") + ylab("Mean error") + theme_bw(base_size=18) +
scale_colour_discrete(name = "Goal babbling proportion") +
geom_line(position = position_dodge(1000)) +
geom_errorbar(aes(ymin=Error-ci,
ymax=Error+ci),
color="black", width=1000,
position = position_dodge(1000)) +
geom_point(position = position_dodge(1000),
size=1.5, fill="white")
This other code, exactly the same except for the facet_wrap line deleted and with shape added works fine:
df.plot.GBPperAIP <- ggplot(df.sum.GBPperAIP,
aes(x=TestIteration, y=Error,
colour=GoalBabblingProp,
shape=AdultInputProp,
group=interaction(GoalBabblingProp,
AdultInputProp))) +
xlab("Step") + ylab("Mean error") + theme_bw(base_size=18) +
scale_colour_discrete(name = "Goal babbling proportion") +
geom_line(position = position_dodge(1000)) +
geom_errorbar(aes(ymin=Error-ci,
ymax=Error+ci),
color="black", width=1000,
position = position_dodge(1000)) +
geom_point(position = position_dodge(1000),
size=1.5, fill="white")
facet_wrap expects a formula, not just a naked variable name. So you should change it to
...
facet_wrap(~ AdultInputProp) +
...
I'd like to smooth the geom_lines and fill the area between. I've tried stat_smooth() to smooth the lines, and both geom_ribbon() and geom_polygon() but without success.
Apologies for the double barrel question.
bell <- data.frame(
month = c("Launch","1st","2nd","3rd","4th","5th","6th","7th","8th","9th","10th","11th","12th"),
rate = c(0,.05,.12,.18,.34,.42,.57,.68,.75,.81,.83,.85,.87))
bell$month <- factor(bell$month, levels = rev(c("Launch","1st","2nd","3rd","4th","5th","6th","7th","8th","9th","10th","11th","12th")))
ggplot() +
theme_minimal() +
coord_flip() +
scale_fill_manual(values=cols) +
geom_line(data=bell, aes(x=month, y=.5-(rate/2), group=1), color='pink', size=1) +
geom_line(data=bell, aes(x=month, y=.5+(rate/2), group=1), color='pink', size=1) +
theme(legend.position='none', axis.ticks=element_blank(), axis.text.x=element_blank(),axis.title.x=element_blank())
One option is to calculate the points of the loess regression outside of ggplot and then plot them using geom_line (for a line) or geom_area for a filled area (geom_area is geom_ribbon, but with ymin fixed at zero).
Also, you don't need coord_flip. Instead, just switch your x and y mappings. This is necessary anyway if you want to fill underneath the curve.
In the example below I've created a numeric month variable for the regression. I've also commented out the scale_fill_manual line because your example doesn't provide a cols vector and the plot code doesn't produce a legend anyway. I've also commented out the legend.position='none' line as it's superfluous.
bell$month.num = 0:12
m1 = loess(rate ~ month.num, data=bell)
bell$loess.mod = predict(m1)
ggplot(bell, aes(y=month, group=1)) +
theme_minimal() +
#scale_fill_manual(values=cols) +
geom_area(aes(x=.5-(loess.mod/2)), fill='pink', size=1) +
geom_area(aes(x=.5+(loess.mod/2)), fill='pink', size=1) +
theme(#legend.position='none',
axis.ticks=element_blank(),
axis.text.x=element_blank(),
axis.title.x=element_blank())
I am trying to produce a circular "heatmap" in R, and found a solution with coord_polar, and how to distribute the labels around the plot.
My problem is that the labels around the plot seem to be centred and the long names are overlapping the plot. I can't use hjust and vjust to align the text to the edge of the plot.
My code and a subset of my data:
library(reshape)
library(ggplot2)
data <- data.frame(id=c("S_subsp_houtenae_str_ATCC_BAA-1581","S_Heidelberg_S_1_7","S_Haifa_S_11_3","S_Infantis_S_2_3","S_Newport_S_1_4","S_Bredeney_S_1_3","S_Saint_Paul_S_1_5","S_Bovismorbificans_S_3_8","S_Saintpaul_str_SARA26","S_London_S_6_7","S_Mbandaka_S_7_5","S_Corvallis_S_5_6","S_San_Diego_S_9_5","S_Javiana_str_10721"),
A.C2=c(0,0,0,0,0,0,0,0,0,0,0,2,0,0),Col156=c(0,0,0,0,0,4,0,0,0,0,0,0,0,0),
ColRNAI=c(0,8,0,0,8,8,8,0,8,0,0,0,0,0),FIB=c(0,0,0,0,10,0,0,10,10,0,0,0,0,0),
FII=c(0,0,0,0,0,0,0,12,12,0,0,0,0,0),HI2=c(0,15,0,0,15,15,0,0,0,0,0,0,0,0),
HI2A=c(0,15,0,0,15,15,0,0,0,0,0,0,0,0),I1=c(0,17,17,17,0,0,0,0,0,0,0,17,17,0),
I2=c(0,0,0,0,0,0,0,0,0,0,0,18,18,18),N=c(0,0,0,0,0,0,0,19,19,19,19,0,0,0),
P=c(20,20,20,20,20,20,20,0,0,0,0,0,0,0),Q1=c(0,22,0,0,22,0,0,0,0,0,0,22,0,0))
data <- transform(data,id=factor(id,levels=unique(id)))
data.m <- melt(data)
data.m$var2 = as.numeric(data.m$variable) + 15
y_labels = levels(data.m$variable)
y_breaks = seq_along(y_labels) + 15
sequence_length = length(unique(data.m$id))
first_sequence = c(1:(sequence_length%/%2))
second_sequence = c((sequence_length%/%2+1):sequence_length)
first_angles =c(90 - 180/length(first_sequence) * first_sequence)
second_angles = c(-90 - 180/length(second_sequence) * second_sequence)
Palette <- c("#f1f1f1","#302013","#614126","#58DB41","#638A5C","#62D585","#579134","#B8DD95","#9ED84D","#4B6FC8","#2A344D","#47689B","#315CEE","#D9AB68","#E09B33","#FE9E2A","#D97B0C","#6A2F45","#A02A77","#E1C73E","#D16F60","#C13420","#DA435C","#E20338","#000000","#999999")
p = ggplot(data.m, aes(x=id, y=var2, fill=factor(value))) +
geom_tile(colour="white") +
scale_fill_manual(values=Palette) +
scale_y_discrete(breaks=y_breaks, labels=y_labels) +
theme(panel.background=element_blank(),
axis.title=element_blank(),
panel.grid=element_blank(),
axis.text.x=element_text(angle= c(first_angles,second_angles),size=8),
axis.ticks=element_blank(),
axis.text.y=element_blank(),
legend.position="none")
p = p + coord_polar()
plot(p)
I've had similar issues in coord_polar() with labels not responding to either hjust= or vjust= and therefore not aligning as I'd like.
The solution to this, shown here https://stackoverflow.com/a/28846989/4340137, is to use geom_text() to manually label the data.
The example at the link provided does everything you need. Unfortunately, I just can't get it working quickly with your more complicated data structure and SO won't let me leave this as a comment.
Someone else may be able to edit to include the exact code.
In RStudio, when I run the following and zoom, all the labels are outside the circle except the longest one, which may mean the plot margin at the top is too tight (or you might consider shortening the name or using \n for a new line). I changed the axis.text.y argument to theme. I also couldn't get the odd legend in the top left to go away. Even so, the inserted plot suffers from the overlap problem you described.
ggplot(data.m, aes(x=id, y=var2, fill=factor(value))) +
geom_tile(colour="white") +
scale_fill_manual(values=Palette) +
scale_y_discrete(breaks=y_breaks, labels=y_labels) +
theme(panel.background=element_blank(), axis.title=element_blank(), panel.grid=element_blank(),
axis.text.x=element_text(angle= c(first_angles,second_angles),size=8, vjust=-1), # vjust=-1
axis.ticks=element_blank(), legend.position="none",
axis.text.y=element_text(vjust = -2), legend.position="none") +
coord_polar()
I have a empirical PDF + CDF combo I'd like to plot on the same panel. distro.df has columns pdf, cdf, and day. I'd like the pdf values to be plotted as bars, and the cdf as lines. This does the trick for making the plot:
p <- ggplot(distro.df, aes(x=day))
p <- p + geom_bar(aes(y=pdf/max(pdf)), stat="identity", width=0.95, fill=fillCol)
p <- p + geom_line(aes(y=cdf))
p <- p + xlab("Day") + ylab("")
p <- p + theme_bw() + theme_update(panel.background = element_blank(), panel.border=element_blank())
However, I'm having trouble getting a legend to appear. I'd like a line for the cdf and a filled block for the pdf. I've tried various contortions with guides, but can't seem to get anything to appear.
Suggestions?
EDIT:
Per #Henrik's request: to make a suitable distro.df object:
df <- data.frame(day=0:10)
df$pdf <- runif(length(df$day))
df$pdf <- df$pdf / sum(df$pdf)
df$cdf <- cumsum(df$pdf)
Then the above to make the plot, then invoke p to see the plot.
This generally involves moving fill into aes and using it in both the geom_bar and geom_line layers. In this case, you also need to add show_guide = TRUE to geom_line.
Once you have that, you just need to set the fill colors in scale_fill_manual so CDF doesn't have a fill color and use override.aes to do the same thing for the lines. I didn't know what your fill color was, so I just used red.
ggplot(df, aes(x=day)) +
geom_bar(aes(y=pdf/max(pdf), fill = "PDF"), stat="identity", width=0.95) +
geom_line(aes(y=cdf, fill = "CDF"), show_guide = TRUE) +
xlab("Day") + ylab("") +
theme_bw() +
theme_update(panel.background = element_blank(),
panel.border=element_blank()) +
scale_fill_manual(values = c(NA, "red"),
breaks = c("PDF", "CDF"),
name = element_blank(),
guide = guide_legend(override.aes = list(linetype = c(0,1))))
I'd still like a solution to the above (and will checkout #aosmith's answer), but I am currently going with a slightly different approach to eliminate the need to solve the problem:
p <- ggplot(distro.df, aes(x=days, color=pdf, fill=pdf))
p <- p + geom_bar(aes(y=pdf/max(pdf)), stat="identity", width=0.95)
p <- p + geom_line(aes(y=cdf), color="black")
p <- p + xlab("Day") + ylab("CDF")
p <- p + theme_bw() + theme_update(panel.background = element_blank(), panel.border=element_blank())
p
This also has the advantage of displaying some of the previously missing information, namely the PDF values.