until now I can't find an appropriate answer, here is my short question about ggplot2 in R:
data(mtcars)
ggplot(data=mtcars, aes(x=mpg, y=wt, fill=factor(cyl))) +
scale_fill_manual(values=c("red","orange","blue"))+
geom_point(size=2, pch=21)+
facet_grid(.~cyl)
This is all fine, now I want all data points (regardless what number cyl has) in every facet (e.g. with a smooth grey below the points)?
Thanks, Michael
Here is a slight simplification that makes life a bit easier. The only thing you need to do is to remove the faceting variable from the data provided to the background geom_point() layer.
library(tidyverse)
ggplot(data=mtcars, aes(x=mpg, y=wt)) +
geom_point(data=select(mtcars,-cyl), colour="grey") +
geom_point(size=2, pch=21, aes(fill=factor(cyl))) +
scale_fill_manual(values=c("red","orange","blue")) +
facet_wrap(~cyl)
Using the link given by #beetroot, I was able to do something like this :
g1 <- ggplot(data=mtcars, aes(x=mpg, y=wt)) +
geom_point(data=mtcars[, c("mpg", "wt")], aes(x=mpg, y=wt), colour="grey") +
geom_point(size=2, pch=21, aes(fill=factor(cyl))) +
scale_fill_manual(values=c("red","orange","blue")) +
facet_wrap(~cyl)
This produces the plot :
Hope this helps you.
Related
I have attached multiple plots to one page using grid.arrange.
Is there a way to label each plot with "(a)","(b)" etc...
I have tried using geom_text but it does not seem compatible with my plots....
.... as you can see, geom_text has some strange interaction with my legend symbols.
I will show an example using the mtcars data of what I am trying to achieve. THe alternative to geom_text I have found is "annotate" which does not interact with my legend symbols. However, it is not easy to label only one facet....
q1=ggplot(mtcars, aes(x=mpg, y=wt)) +
geom_line() +
geom_point()+
facet_grid(~cyl)+
annotate(geom="text", x=15, y=12, label="(a)",size=8,family="serif")
q2=ggplot(mtcars, aes(x=mpg, y=wt,)) +
geom_line() +
geom_point()+
facet_grid(~cyl)+
annotate(geom="text", x=15, y=12, label="(b)",size=8,family="serif")
geom_text(x=15, y=5,size=8, label="(b)")
gt1 <- ggplotGrob(q1)
gt2 <- ggplotGrob(q2)
grid.arrange(gt1,gt2, ncol=1)
Therefore, my question is, is there a way to label plots arranged using grid.arrange, so that the first facet in each plot is labelled with either a, or b or c etc...?
You can use ggarrange from ggpubr package and set labels for each plot using the argument labels:
library(ggplot2)
library(ggpubr)
q1=ggplot(mtcars, aes(x=mpg, y=wt)) +
geom_line() +
geom_point()+
facet_grid(~cyl)+
annotate(geom="text", x=15, y=12, label="(a)",size=8,family="serif")
q2=ggplot(mtcars, aes(x=mpg, y=wt,)) +
geom_line() +
geom_point()+
facet_grid(~cyl)+
annotate(geom="text", x=15, y=12, label="(b)",size=8,family="serif")
ggarrange(q1,q2, ncol = 1, labels = c("a)","b)"))
Is it what you are looking for ?
If you set inherit.aes=FALSE, you can prevent it from interring:
ggplot(mtcars, aes(x=mpg, y=wt,col=factor(cyl))) +
geom_line() +
geom_point()+
geom_text(inherit.aes=FALSE,aes(x=15,y=12,label="(a)"),
size=8,family="serif")+
facet_grid(~cyl)
If you want to only label the first facet (hope I got you correct), I think the easiest way to specify a data frame, e.g if we want only something in the first,
#place it in the first
lvl_data = data.frame(
x=15,y=12,label="(a)",
cyl=levels(factor(mtcars$cyl))[1]
)
ggplot(mtcars, aes(x=mpg, y=wt,col=factor(cyl))) +
geom_line() +
geom_point()+
geom_text(data=lvl_data,inherit.aes=FALSE,
aes(x=x,y=y,label=label),size=8,family="serif")+
facet_grid(~cyl)
I want to have a horizontal bar chart, but without legend. When I run the script below without coord_flip(), no legend shows. But when I run it with the coord_flip() argument, the legend appaers. I think this might be a bug. Does anyone know a different code with which I can skip the legend?
df <- aggregate(formula=mpg~cyl, data=mtcars, FUN=sum)
fig <- ggplot(df, aes(x=cyl, y=mpg, fill=cyl, label=mpg)) +
geom_col() +
coord_flip() +
theme(legend.position="none") +
theme_bw()
fig
I have a very simple problem that I am struggling with, namely changing the legends of plot using geom_smooth in ggplot2.
Here is my code:
p1<- mtcars$group <- factor(mtcars$vs)
ggplot(mtcars, aes(x=mpg, y=disp, group=group)) +
geom_smooth(method=lm, se=FALSE,fullrange=TRUE, show.legend=TRUE,aes(linetype=group), colour="black")
p1
result of p1
What I would like to do, is change the labels: i.e.: from "group" to "legend" and from "0" to "Experiment" and "1" to "Control". I tried to do this by addeding the labs argument and using scale_fill_discrete:
p2<- ggplot(mtcars, aes(x=mpg, y=disp, group=group)) +
geom_smooth(method=lm, se=FALSE,fullrange=TRUE, show.legend=TRUE,aes(linetype=group), colour="black")+
labs(linetype="Legend")+
scale_fill_discrete(labels=c("Experiment", "Control"))
p2
The result changes the legend title, (p2) but still does not change the labels. Any ideas?
EDIT:
This solves the problem, thanks for the quick replies:
ggplot(mtcars, aes(x=mpg, y=disp, group=group)) +
geom_smooth(method=lm, se=FALSE,fullrange=TRUE, show.legend=TRUE,aes(linetype=group), colour="black")+
labs(linetype="Legend")+
scale_linetype_discrete(labels=c("Experiment", "Control"))
My mistake was using scale_fill_discrete instead of scale_linetype_discrete.
Do you get the error if you run the code like this?
ggplot(mtcars, aes(x=mpg, y=disp, group=group)) +
geom_smooth(method=lm, se=FALSE,fullrange=TRUE, show.legend=TRUE,aes(linetype=group), colour="black")+
labs(linetype="Legend")+
scale_linetype_discrete(labels=c("Experiment", "Control"))
I get this plot:
I've created a side-by-side boxplot using ggplot2.
p <- ggplot(mtcars, aes(x=factor(cyl), y=mpg))
p + geom_boxplot(aes(fill=factor(cyl)))
I want to annotate with min, max, 1st quartile, median and 3rd quartile in the plot. I know geom_text() can do so and may be fivenum() is useful. But I cannot figure out how exactly I can do!. These values should be displayed in my plot.
The most succinct way I can think of is to use stat_summary. I've also mapped the labels to a color aesthetic, but you can, of course, set the labels to a single color if you wish:
ggplot(mtcars, aes(x=factor(cyl), y=mpg, fill=factor(cyl))) +
geom_boxplot(width=0.6) +
stat_summary(geom="text", fun.y=quantile,
aes(label=sprintf("%1.1f", ..y..), color=factor(cyl)),
position=position_nudge(x=0.33), size=3.5) +
theme_bw()
In the code above we use quantile as the summary function to get the label values. ..y.. refers back to the output of the quantile function (in general, ..*.. is a ggplot construction for using values calculated within ggplot).
One way is to simply make the data.frame you need, and pass it to geom_text or geom_label:
library(dplyr)
cyl_fivenum <- mtcars %>%
group_by(cyl) %>%
summarise(five = list(fivenum(mpg))) %>%
tidyr::unnest()
ggplot(mtcars, aes(x=factor(cyl), y=mpg)) +
geom_boxplot(aes(fill=factor(cyl))) +
geom_text(data = cyl_fivenum,
aes(x = factor(cyl), y = five, label = five),
nudge_x = .5)
In case anyone is dealing with large ranges and has to log10 transform their y-axis, I found some code that works great. Just add 10^..y.. and scale_y_log10(). If you don't add 10^ before ..y.. the actual quantile values will be log transformed and displayed as such.
Does not work
ggplot(mtcars, aes(x=factor(cyl), y=mpg, fill=factor(cyl))) +
geom_boxplot(width=0.6) +
stat_summary(geom="text", fun.y=quantile,
aes(label=sprintf("%1.1f", ..y..), color=factor(cyl)),
position=position_nudge(x=0.45), size=3.5) +
scale_y_log10()+
theme_bw()
Works great
ggplot(mtcars, aes(x=factor(cyl), y=mpg, fill=factor(cyl))) +
geom_boxplot(width=0.6) +
stat_summary(geom="text", fun.y=quantile,
aes(label=sprintf("%1.1f", 10^..y..), color=factor(cyl)),
position=position_nudge(x=0.45), size=3.5) +
scale_y_log10()+
theme_bw()
I am trying to plot the outliers and mean point for the box plots in below using the data available here. The dataset has 3 different factors and 1 value column for 3600 rows.
While I run the below the code it shows the mean point but doesn't draw the outliers properly
ggplot(df, aes(x=Representations, y=Values, fill=Methods)) +
geom_boxplot() +
facet_wrap(~Metrics) +
stat_summary(fun.y=mean, colour="black", geom="point", position=position_dodge(width=0.75)) +
geom_point() +
theme_bw()
Again, while I am modify the code like in below the mean points disappear !!
ggplot(df, aes(x=Representations, y=Values, colour=Methods)) +
geom_boxplot() +
facet_wrap(~Metrics) +
stat_summary(fun.y=mean, colour="black", geom="point", position=position_dodge(width=0.75)) +
geom_point() +
theme_bw()
In both of the cases I am getting the message: "ymax not defined: adjusting position using y instead" 3 times.
Any kind suggestions how to fix it? I would like to draw the mean points within individual box plots and show outliers in the same colour as the plots.
EDIT:
The original data set does not have any outliers and that was reason for my confusion. Thanks to MrFlick's answer with randomly generated data which clarifies it properly.
Rather than downloading the data, I just made a random sample.
set.seed(18)
gg <- expand.grid (
Methods=c("BC","FD","FDFND","NC"),
Metrics=c("DM","DTI","LB"),
Representations=c("CHG","QR","HQR")
)
df <- data.frame(
gg,
Values=rnorm(nrow(gg)*50)
)
Then you should be able to create the plot you want with
library(ggplot2)
ggplot(df, aes(x=Representations, y=Values, fill=Methods)) +
geom_boxplot() +
stat_summary(fun.y="mean", geom="point",
position=position_dodge(width=0.75), color="white") +
facet_wrap(~Metrics)
which gave me
I was using ggplot2 version 0.9.3.1