Change legend shape size for fill using geom_bar - r

Here is my reproducible code:
This is an example of what I want my actual figure to look like.
library(tidyverse)
p <- mtcars %>%
mutate(cyl = factor(cyl)) %>%
ggplot(aes(carb)) +
geom_bar(aes(fill = cyl)) +
scale_fill_manual(values = c("Red","Green","Blue"))
Resulting figure:
Problem:
What I want to change is in the legend. The boxes depicting the color of the bars on the histogram are too big and I want to reduce the size.
Attempted Solutions:
I have tried this code from another stackoverflow question and it does not work:
p <- p + guides(fill = guide_legend(override.aes = list(width = .5)))
In the reference stackoverflow question, another user suggested making a dummy geom_point variable and then using that legend as the legend and removing the fill legend. I would rather not have to do that if possible.
Thank you for the help.

Use legend.key.size (or legend.key.height and legend.key.width). E.g., add
theme(legend.key.size = unit(0.1, "cm"))
to your plot

Related

How to add a minor grid in boxplots in ggplot2?

I want to add a vertical minor grid between two major grids in a boxplot with discrete x variables in ggplot2.
This is the sample:
boxplot <- ggplot(data = mtcars ,aes(x = as.factor(cyl),y=wt, fill=as.factor(am))) + geom_boxplot()
boxplot
As seen from the visualization, it can be unclear which box belongs to which x label because the major vertical grid is separating the two boxes at the same x-variable (it may not be an issue here, but it does become problematic when there are many x variables and narrow boxes). Therefore, I am thinking of adding a minor grid in the middle of each major grid. I tried using the "minor grid.x" in ggplot2, shown below, but I could not see any added lines.
boxplot + theme(panel.grid.minor.x = element_line(color="black"))
I've looked over related posts on setting gridlines, but it seems that they are focused on continuous x variables, and is not applicable to box plots.
Thank you in advance.
Update thanks to #Allan Cameron:
ggplot(data = mtcars ,aes(x =factor(cyl),y=wt, fill=as.factor(am))) +
geom_boxplot() +
geom_vline(xintercept = c(1.5, 2.5),linetype="dashed",colour="green",size=1)
First answer:
Are you looking for such a solution:
library(ggplot2)
ggplot(data = mtcars ,aes(x =factor(cyl),y=wt, fill=as.factor(am))) +
geom_boxplot() +
geom_vline(aes(xintercept=1.5),linetype="dashed",colour="green",size=1)+
geom_vline(aes(xintercept=2.5),linetype="dashed",colour="green",size=1)
You can try this and modify the values of the theme and see what works better for you:
boxplot +
theme(
panel.grid.major.y = element_line(color = "blue",
size = 0.5,
linetype = 2),
panel.grid.minor.y = element_line(color = "red",
size = 0.25,
linetype = 1),
panel.grid.major.x = element_line(color = "green",
size = 0.5,
linetype = 3)
)

ggplot2: add horizontal line by group inside facet_grid

I want to draw a dot plot with horizontal lines by groups.
The df object store the points and the df.line object stores the line I want to add to the dot plot. The horizontal lines are not the mean/median value of points, they are some standards I want to show in this figure.
I tried gome_hline, geom_line, geom_errorbar, and stat_summary. but none of them work as I want.
Could anyone teach me how to do it?
library(ggplot2)
library(tidytext)
set.seed(42)
df=data.frame(site=c(rep("a",5),rep("b",5),rep("c",5)),
sample=c(1:5,1:5,1:5),
value=c(runif(5, min=0.54, max=0.56),runif(5, min=0.52, max=0.6),runif(5,
min=0.3, max=0.4)),
condition=c(rep("c1",5),rep("c2",5),rep("c2",5)))
df.line=data.frame(site=c("a","b","c"),standard=c(0.55,0.4,0.53))
ggplot(df)+
geom_point(aes(x=tidytext::reorder_within(site,value,condition,fun=mean),
y=value))+
facet_grid(~condition,space="free_x",scales = "free_x")+
scale_x_reordered()
First, merge df and df.line together. Next, move the main aes() call to ggplot so it can be used later. Then use stat_summary:
library(dplyr)
merge(df,df.line) %>%
ggplot(aes(x=tidytext::reorder_within(site,value,condition,fun=mean),
y=value))+
geom_point()+
stat_summary(aes(y = standard, ymax = after_stat(y), ymin = after_stat(y)),
fun = mean, geom = "errorbar", color = "red", width = 0.3) +
facet_grid(~condition,space="free_x",scales = "free_x")+
scale_x_reordered()

Change title legend position using guides() without breaking the legend into discrete numbers

I was wondering if you can help me out with a (probably silly) problem with my code that is driving me nuts. I'm using R and my problems are with the package sf + ggplot2. Is there anyone out there that can help me?. I found a similar question here, but the solution is not exactly what I need.
I'm trying to plot a numeric variable on a map using the sf package. The variable is numeric and I want the legend to be on a continuous scale. I managed to do that, the problem started when I used the "guides" option to position the title of the legend on top. Here is a reproducible example:
library(sf)
demo(nc, ask = F, echo = F)
ggplot() +
geom_sf(data = nc, aes(fill = BIR74)) +
scale_y_continuous(breaks = 34:36) +
theme(legend.position="bottom",
legend.direction = "horizontal")
This code produces this map:. You can see that the scale of the Bir74 is continuous. If I use guides(fill = guide_legend(title.position = “top”), it will work for placing the title of the legend on top, but the legend label is on a discrete scale now. This is an example
ggplot() +
geom_sf(data = nc, aes(fill = BIR74)) +
scale_y_continuous(breaks = 34:36) +
theme(legend.position="bottom",
legend.direction = "horizontal") +
guides(fill = guide_legend(title.position = "top"))
and this is the map resulting:
What I really want is the legend placed at the bottom with the title on top as in map 2, but with the legend on the scale of map 1.
Any help on how to solve this would be massively appreciated!
Cheers!

Put legend under each facet using facet_grid; adding one title and one caption to plot

I'm working with a plot analogous to the following:
ggplot(data=mtcars, aes(x=wt, y=mpg, color=carb)) +
geom_line() + facet_grid(gear ~ .) +
ggtitle(expression("Title")) +
labs(caption = "Sources: Compustat, Author's Calculations") +
theme(plot.title = element_text(size = 20, hjust = 0.5),
plot.caption=element_text(size=8, hjust=.5),
strip.background = element_blank(),
strip.text = element_blank(),
legend.title = element_blank())
I'm trying to do the following:
Insert a legend beneath each of the 3 facets, each legend specific to the facet above it.
Insert one plot title (as opposed to the same title above each facet).
Insert one caption beneath the final facet (as opposed to three captions beneath each facet).
I was able to reproduce this example on assigning a legend to each facet.
However, the plot title was placed above and the caption below each facet. Also, this example uses facet_wrap and not facet_grid.
Thank you in advance.
library(dplyr)
library(ggplot2)
tempgg <- mtcars %>%
group_by(gear) %>%
do(gg = {ggplot(data=., aes(x=wt, y=mpg, color=carb)) +
geom_point() +
labs(x = NULL) +
guides(color = guide_colorbar(title.position = "left")) +
theme(plot.title = element_text(size = 20, hjust = 0.5),
plot.caption=element_text(size=8, hjust=.5),
legend.position = "bottom")})
tempgg$gg[1][[1]] <- tempgg$gg[1][[1]] + labs(title = "Top title")
tempgg$gg[3][[1]] <- tempgg$gg[3][[1]] + labs(x = "Axis label", caption = "Bottom caption")
tempgg %>% gridExtra::grid.arrange(grobs = .$gg)
This isn't the most elegant way to do it. Each of the three grobs gets an equal space when you grid.arrange them, so the first and last ones are squished from the title and caption taking up space. You could add something like heights = c(3,2,3) inside the grid.arrange call, but you'd have to fiddle with each of the heights to get it to look right, and even then it would be a visual approximation, not exact.
To do it the more precise way, you'd need to look at the underlying gtables in each of the grobs. https://stackoverflow.com/users/471093/baptiste is the expert on that.
Update:
I used a #baptiste solution, which is still not particularly elegant, but gives you the same plot space for each panel. Use this snippet in place of the last line above.
tempggt <- tempgg %>% do(ggt = ggplot_gtable(ggplot_build(.$gg))) %>% .$ggt
gg1 <- tempggt[[1]]
gg2 <- tempggt[[2]]
gg3 <- tempggt[[3]]
gridExtra::grid.arrange(gridExtra::rbind.gtable(gg1, gg2, gg3))

Legend title position in ggplot2

Anone know how to change the position of the legend title in ggplot?
I have used the following code to move the legend to the bottom and make it horizontal
p <- p + opts(legend.position = 'bottom', legend.direction = 'horizontal')
But now I want the title to be to the left of the legend instead of above. I've looked in the follwing places but cant find it or figure it out:
https://github.com/hadley/ggplot2/wiki/Legend-Attributes
http://had.co.nz/ggplot2/book/toolbox.r
Any assistance would be greatly appreciated
Using the transition guide to version 0.9 as a reference, you might try the following (assuming you want to change the title position for the colour legend):
library(scales)
+ guides(colour = guide_legend(title.position = "left"))
For a continuous scale you'd use guide_colorbar instead of guide_legend.
Just to provide a concrete example to prove I'm not just making this up,
library(ggplot2)
library(scales)
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point(aes(colour = qsec)) +
guides(colour = guide_legend(title.position = "right"))

Resources