when we use the facet option in ggplot, we get a beautiful grey box around the headings (3,4,5).
library(ggplot2)
data(mtcars)
ggplot(mtcars, aes(cyl)) + geom_bar() + facet_wrap(~gear) + theme_bw()
How can we place a similiar grey box around the chart title when we do no use the facet option?
ggplot(mtcars, aes(cyl)) + geom_bar() + theme_bw() +
ggtitle("How do you put a grey box around me??")
Since you are asking how to do it without facets, this is strictly speaking not an answer, but just to point it out, one quick and dirty way would be to "cheat" and to use a facet after all. For instance,
mtcars$title <- "How do you put a grey box around me??"
ggplot(mtcars, aes(cyl)) + geom_bar() + theme_bw() +
facet_grid(. ~ title)
does the trick.
you can use annotate and change plot title margin, then from annotate you can use "rect" geom for annotation:
ggplot(mtcars, aes(x = factor(cyl))) +
geom_bar() +
theme_bw() +
ggtitle(" How do you put a grey box around me??") +
theme(panel.grid = element_blank(),
panel.border = element_blank(),
axis.line.x = element_line(color = "black"),
axis.line.y = element_line(color = "black"),
plot.title = element_text(size = 12, color = "black", face = "bold", margin = margin(t = 10, b = -30)))+
annotate("rect",xmin=0,xmax=3,ymin=14,ymax=15,alpha=.2,color="black", linetype = 'dotted', fill = "grey1")
Title with borders from annotate
The other best and easy solution to save image as SVG then open it from inkscape 'free software' and then easily add rectangle to the title:
Title grey box using inkscape
Related
So I have a ggplot that doesn't require a legend because it actually has a title and thus doesn't need a legend that would simply repeat the title.
Imagine something like this:
ggplot(iris)+
geom_point(aes(x=Sepal.Length, y=Sepal.Width, color=Species))+
theme(legend.box.background=element_rect(fill="white", color="black"))+
labs(color="")+
ggtitle("Sepals ~ Species")+
xlab("Length")+
ylab("Width")
(ignore the fact that the legend in my reprex only has two lines drawn for the box)
Do you notice the graphical problem? Apparently ggplot "thinks" there is a legend title and leaves some space, so I though using element_blank for the legend title might work.
ggplot(iris)+
geom_point(aes(x=Sepal.Length, y=Sepal.Width, color=Species))+
labs(color=element_blank())+
theme(legend.box.background=element_rect(fill=NA, color="black"),
legend.margin=margin(t=0,r=0,b=0,l=0))+
ggtitle("Sepals ~ Species")+
xlab("Length")+
ylab("Width")
While this improves the situation by making the box smaller at the top, it does not fix the problem because the top space is still smaller. As I have manually set the legend margins to 0 this can't be the issue.
any ideas?
You can set theme(legend.title = element_blank()) . This also means you don't need to set an empty string for the label.
To show this, let's make that box outline a little thicker, and use the "empty string" method:
ggplot(iris) +
geom_point(aes(Sepal.Length, Sepal.Width, color = Species)) +
ggtitle("Sepals ~ Species") +
labs(x = "Length", y = "Width", color = "") +
theme(legend.box.background = element_rect(color ="black", size = 2))
We can see that there is an obvious space where the title should be.
But now let's try it with the element_blank() method:
ggplot(iris) +
geom_point(aes(Sepal.Length, Sepal.Width, color = Species)) +
ggtitle("Sepals ~ Species") +
labs(x = "Length", y = "Width") +
theme(legend.box.background = element_rect(color ="black", size = 2),
legend.title = element_blank())
As Tjebo points out, the other option is to use NULL instead of an empty string, which does the same thing as theme(legend.title = element_blank())
ggplot(iris) +
geom_point(aes(Sepal.Length, Sepal.Width, color = Species)) +
ggtitle("Sepals ~ Species") +
labs(x = "Length", y = "Width", color = NULL) +
theme(legend.box.background = element_rect(color ="black", size = 2))
You additionally need to change legend.spacing. Very related: Reduce padding in ggplot2 legend
By the way, margin() has as defaults all = 0, so you don't need to type them out... ;)
library(ggplot2)
ggplot(iris)+
geom_point(aes(x=Sepal.Length, y=Sepal.Width, color=Species))+
labs(color=NULL) +
theme(legend.box.background=element_rect(fill="white", color="black"),
legend.margin=margin(),
legend.spacing.y = unit(0, "mm"))
Created on 2022-05-31 by the reprex package (v2.0.1)
I want to add a legend it shows black for the 7 day moving average and blue for the bars(daily cases). so it looks something similar to the NHS graph , but the legend does not work when i add it into my code?
ggplot(LimerickNew1, aes(x=TimeStamp, y=DailyCCase,Shape=MA7)) +
geom_bar(stat="identity",fill="steelblue") +
geom_line(aes(y=MA7),size=1.5) +
labs( x="", y="Total cases", title="Total Covid Cases for County Limerick 01-03-20 to 01-
06-`20" )+`
theme_bw()+
theme(legend.background = element_rect(fill = "darkgray"),
legend.key = element_rect(fill = "lightblue", color = NA),
legend.key.size = unit(1.5, "cm"),
legend.key.width = unit(0.5,"cm"),
axis.text.x = element_text(face="bold", color="#008000",size=12, angle=0),
axis.text.y = element_text(face="bold", color="#008000",size=12, angle=0),
axis.title.x = element_text(face="bold", size=12, color="black"),
plot.title = element_text( face = "bold", colour = "black", size = 20,, hjust = 0.5))
Without a reproducible example, it's hard to give a more specific answer for your question, but here's a method that expands upon the comment from #teunbrand and should guide you toward showing a legend.
TL;DR - The reason you're not seeing a legend is because you do not have any layers or geoms drawn that have one of the aesthetics mapped to aes(). All aesthetics like color, size, and fill are specified for each geom outside of an aes() function, which means there's no reason for ggplot2 to draw a legend. To get a legend to be drawn, you need to specify the aesthetic inside aes().
Example
Here's an illustrative example that is similar to OP's question.
library(ggplot2)
set.seed(8675309)
df <- data.frame(
x = 1:100,
y = rnorm(100, 10))
df$z <- log(cumsum(df$y))
ggplot(df, aes(x=x)) +
geom_col(aes(y=y), fill='blue', alpha=0.3) +
geom_line(aes(y=z), size=2) +
ylim(0,25) + theme_bw()
Showing a Legend
To get a legend to show, you have to specify one or more aesthetics inside aes(). The fun fact here is that you don't have to specify a column in the dataset when doing this. If you specify a single value, it will apply to the whole dataset, and basically just show a legend key for the entire set of observations. This is what we want.
ggplot(df, aes(x=x)) +
geom_col(aes(y=y, fill="the columns"), alpha=0.3) +
geom_line(aes(y=z, size="the line"), color="black") +
ylim(0,25) + theme_bw()
Formatting
The names come from the values specified in aes(), and the color change is due to default mapping of color values. To get things to look "right", you want to use some theme() elements to:
keep only one name
squish legends together
position on the chart, rather than on the side
The end result is here:
ggplot(df, aes(x=x)) +
geom_col(aes(y=y, fill="the columns"), alpha=0.3) +
geom_line(aes(y=z, size="the line"), color="black") +
ylim(0,25) +
scale_fill_manual(values="blue") + # recolor the columns
guides(
fill=guide_legend(title="My Legend", order=1),
size=guide_legend(title=NULL, order=2)
) +
theme_bw() +
# legend placement and spacing
theme(
legend.title = element_text(margin=margin(b=10)),
legend.spacing.y = unit(-3,'pt'),
legend.position = c(0.8, 0.8)
)
I'm struggling to plot a gradient color scale for each facet in facet_wrap() independently.
Data is too big to post it here but here is my code:
ggplot(stack, aes(hour, day)) +
geom_tile(aes(fill = percent), colour = "white") +
facet_wrap(~author, ncol = 3) +
theme_minimal() +
scale_fill_distiller(palette = 'RdYlBu') +
theme(
axis.title.x = element_blank(), axis.title.y = element_blank(),
legend.position = "none",
strip.background = element_rect(fill = '#E5E6E1'),
strip.text = element_text(face = 'bold')
)
However, if I plot individually only one author, I get:
I just wanna plot each facet with its own gradient color scale, not share with the rest of the facets. Should be very simple, but I don't manage to do it. I tried adding group = author within aes() in geom_tile() and ggplot() but it wouldn't work.
After much research, I ended up using the solution provided here that uses gridExtra. I guess there is no easy way to do it using only ggplot.
Hi im trying to add my legend area to my plot area without the white borders around my key. So far i have this:
Legend in plot area but white border present:
Legend style i want:
ggplot(data=Pig, aes(x=breed, y= p1_plus_p3_fat_depth_mm, color=sex))+
geom_boxplot()+
theme(legend.title=element_blank()) +
theme(panel.grid.major = element_blank()) +
theme(panel.grid.minor = element_blank())+
xlab("Pig Breed") +
ylab("The P1 and P3 Fat Depth in mm")+
scale_colour_discrete(name ="Sex",breaks=c("B", "S"),labels=c("Boar", "Sow"))+
theme(legend.justification = c(1, 1), legend.position = c(1, 1))+
theme(legend.background = element_rect(fill="transparent"))
You will need to use legend.key = element_blank() to drop the background and borders around the boxplot icons.
ggplot(data=iris[c("Species", "Sepal.Length")], aes(x=Species, y= Sepal.Length, color=Species))+
geom_boxplot()+
theme(legend.title=element_blank()) +
theme(panel.grid.major = element_blank()) +
theme(panel.grid.minor = element_blank())+
theme(legend.justification = c(1, 1), legend.position = c(1, 1))+
theme(legend.background = element_blank(),
legend.key = element_blank())
I prefer using element_blank() which will remove a theme element as opposed to setting it to transparent and leaving it there. I've found depending on the graphics device the transparent can be interpreted differently.
I’m working with faceted plots and I’m having an issue trying to move facet labels that have two lines near the plotting area.
Consider the minimal example:
require(ggplot2)
labs <- as_labeller(c(`0` = "LABEL 1",
`1` = "LABEL 2 HAS TWO LINES\nBECAUSE IT'S TOO LONG"))
p <- ggplot(mtcars, aes(disp, drat)) +
geom_point() +
theme_bw() +
geom_hline(yintercept=2, linetype="solid") +
geom_vline(xintercept=50, linetype="solid") +
scale_x_continuous(limits=c(50,500), expand =c(0,0)) +
scale_y_continuous(limits = c(2, 5), expand = c(0,0)) +
theme(panel.border = element_blank(),
strip.background = element_blank(),
strip.text = element_text(size=9),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
facet_wrap(~am, labeller = labs)
p
Now adding vjust=-0.62 to move the facet labels near the plotting area we have the following:
p + theme(strip.text = element_text(size=9, vjust=-0.62))
As you can see only LABEL 1, the single line label, is moved close to the plotting area - and that’s the problem.
I wished that both labels could have moved. Does anyone have any suggestion?
*Observation: I’m working with a considerable amount of faceted plots so making and customizing plots one-by-one doesn’t seem to be a good idea.
Hope this may helpful for you
p + theme(strip.text = element_text(size=9, vjust=1))