Offset/jitter (?) legend in dotplot - r

I'm likely not using the correct terminology, but the issue is that when creating a dotplot that uses pointrange and multiple groups, the groups as defined in the legend is indistinguishable because the pointrange covers the color of each group (see red rectangle in figure). Is there anyway to either remove the pointrange in the legend (or another solution).
p <- ggplot(ToothGrowth, aes(x=dose, y=len, fill = dose)) + geom_dotplot(binaxis='y', stackdir='center', dotsize = .5, alpha = .25)
p + stat_summary(fun.data=mean_sdl,fun.args = list(mult=1),geom="pointrange", color="black", size = 1)
Thanks for your time.

Try this. You can enable show.legend = F in the last part of your code so that the element will not appear in the legend. Here the code (No output showed as no data was shared):
library(ggplot2)
#Code
p <- ggplot(ToothGrowth, aes(x=dose, y=len, fill = dose)) +
geom_dotplot(binaxis='y', stackdir='center',
dotsize = .5, alpha = .25)
p + stat_summary(fun.data=mean_sdl,fun.args = list(mult=1),
geom="pointrange", color="black", size = 1,show.legend = F)

Or you can use the guides(fill = FALSE) function or scale_fill_discrete(guide = FALSE)
p + guides(fill = FALSE)
or
p + scale_fill_discrete(guide = FALSE)

Related

Merge legend in ggplot when the geoms are different

I have the following code which yields the figure below:
ggplot(data=data.frame(x=x, y=y, mass=mass)) +
geom_line(mapping = aes(x=x, y=y, linetype='Gompertz predicted mass', col='Gompertz predicted mass')) +
geom_point(mapping = aes(x=x, y=mass, shape='Actual mass',col='Actual mass')) +
theme_bw() +
ylab('Mass') +
xlab('t') +
scale_color_manual(name='',values = c("black",'red')) +
scale_linetype_manual(name='',values = c("solid")) +
scale_shape_manual(name='', values = c(19)) +
scale_x_continuous(breaks=seq(4,26,2)) +
ylim(c(0, 20000)) +
ggtitle('Problem 3: Plot of tumor mass with time')
Notice how the legend is separated. I'd like to merge it for shape and color. When the geoms are the same, the technique of using scale_something_manual works perfectly fine to merge the legends. However, I'm having trouble with it here since I have two different geoms.
The problem is similar to the one described in https://github.com/tidyverse/ggplot2/issues/3648. There is no elegant solution at the moment. Because you haven't included any data, I've presumed that your problem is conceptually similar to the plot below:
library(ggplot2)
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(shape = "Point", colour = "Point")) +
geom_smooth(aes(linetype = "Line", colour = "Line"),
formula = y ~ x, se = FALSE, method = "loess") +
scale_colour_manual(values = c("red", "black")) +
scale_linetype_manual(values = "solid") +
scale_shape_manual(values = 19)
The way to fix the problem is to get rid of the linetype and shape aesthetics and scales, and instead override aesthetics at the level of the legend.
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(colour = "Point")) +
geom_smooth(aes(colour = "Line"),
formula = y ~ x, se = FALSE, method = "loess") +
scale_colour_manual(
values = c("red", "black"),
guide = guide_legend(override.aes = list(shape = c(NA, 19),
linetype = c(1, NA)))
)
Created on 2021-09-04 by the reprex package (v2.0.1)

geom_path is not drawing a line

I'm making depth profiles with ggplot. Some of the lines are drawn between the variable points using geom_path but some are not, even when I try adding "group=1" (which was the only solution I've found for this problem). I'm doing multiple plots for different lakes and for each lake there is one or multiple variables not getting a line by using geom_path. For the code below only the Chl.a variable is not drawing a line, all the others do. What could this depend on?
I also tried geom_line instead but this only worked for some variables since the it draws the line following the x-axis, but I want the line to go vertically following the y-axis. Can I achieve this using geom_line since geom_path doesn't seem to work for all variables?
gs <- ggplot(goodspirit, aes(y=goodspirit$Depth.m)) +
geom_point(aes(x=Temp, colour= "Temp")) +
geom_path(aes(x=Temp, color = "Temp"), size=1.5) +
geom_point(aes(x=zDOmg, color ="z(DO mg/L)")) +
geom_path(aes(x=zDOmg, color ="z(DO mg/L)"), size=1.5) +
geom_point(aes(x=Chl.a, color ="Chl.a"), na.rm = TRUE) +
geom_path(aes(x=Chl.a, color ="Chl.a"), na.rm = TRUE, size=1.5) +
geom_point(aes(x=zN2O, color ="z(N2O.nM)"), na.rm = TRUE) +
geom_line(aes(x=zN2O, color ="z(N2O.nM)"), na.rm = TRUE, size=1.5) +
geom_point(aes(x=Sal.ppt, color ="Salinity.ppt"), na.rm = TRUE) +
geom_line(aes(x=Sal.ppt, color ="Salinity.ppt"), na.rm = TRUE, size=1.5)+
geom_point(aes(x=zph, color ="z(pH)")) +
geom_path(aes(x=zph, color ="z(pH)"), size=1.5) +
scale_x_continuous(position = "top", limits=c(-3,5), expand = c(0,0))+
scale_y_reverse(expand = c(0.05,0))+
ylab("Depth (m)") + xlab("x") + ggtitle("Good spirit lake") + labs(colour
= "Parameters") +
theme(plot.title = element_text(hjust = 0.5)) + theme_light()
gs
enter image description here

Combining legends for two different aesthetics fails

library(ggplot2)
x <- data.frame(Specimen=c("A","B","C","D"), Value=rep(0.5,4),
Type=c("c1","c1","c2","c2"), Treatment=factor(rep("A", 4)),
bar=c("hot", "cold", "cold", "cold"))
list2env(split(x, x$Type), envir = .GlobalEnv)
p1 <- ggplot() +
geom_bar(data=c1, aes(x = Treatment, y = Value, fill = Specimen, colour=bar),
stat="identity", position="fill", width=0.5) +
scale_fill_manual("",values=c("gold", "green"))+
scale_color_manual("",values=c("gray40","black")) +
scale_y_continuous(expand = c(0, 0),labels = scales::percent) +
theme(legend.position = "bottom") +
coord_flip()
p2 <- ggplot() +
geom_bar(data=c2, aes(x = Treatment, y = Value, fill = Specimen),
stat="identity", position="fill", col="gray40", width=0.5) +
scale_fill_manual("",values=c("red", "blue"))+
scale_y_continuous(expand = c(0, 0),labels = scales::percent) +
theme(legend.position = "bottom",
axis.text.y=element_blank()) +
xlab("")+
coord_flip()
library(cowplot)
plot_grid(p1,p2, nrow=1, align="v")
In this example, i had to shut down the guide for color, as i couldnt combine it with the guide for fill, despite following the guidelines proposed in this question.
After turning off the guide for col in p1 (guide=F), the legends now appear to be differently drawn (one with col="gray40", the other without any border, as the col-guide is set to false):
]1
How to combine the two legends in p1?
fill and color are mapped to two different varaibles, it's only by chance that in this (trivial) case "A" is always "hot" and "B" is always "cold".
You can map both fill and color to Specimen or bar, but different variable will always result in different legends.
An alternative may be to create an interaction between the two varaibles:
library(ggplot2)
ggplot() +
geom_col(data=c1, aes(x = Treatment,
y = Value,
fill = interaction(Specimen, bar, sep = '-'),
color = interaction(Specimen, bar, sep = '-')),
position="fill", width=0.5) +
scale_fill_manual("",values=c("gold", "green")) +
scale_color_manual("",values=c("gray40", "black")) +
scale_y_continuous(expand = c(0, 0),labels = scales::percent) +
theme(legend.position = "bottom") +
coord_flip()
Created on 2018-05-08 by the reprex package (v0.2.0).

ggplot2: force legend to have one row when guides does not appear to have an effect

I have the following toy example:
library(ggplot2)
g <- ggplot(mpg, aes(class))
mpg$drv <- sample(as.character((-4:4)), size = length(mpg$drv), replace = T)
g + geom_bar(aes(fill = drv), position = "fill") + theme(legend.position = "bottom") + guides(colour = guide_legend(nrow = 1))
which for me yields the following figure.
Try as I might, I am unable to get the legend at the bottom to be in one row. I looked around and the guide_legend appears to be having no effect. Is there a better way to do this, or is there another way to force the legend to be in one row?
You've specified colour instead of fill in guides. Try this instead:
library(ggplot2)
mpg$drv <- sample(as.character((-4:4)), size = length(mpg$drv), replace = T)
g <- ggplot(mpg, aes(class))
g + geom_bar(aes(fill = drv), position = "fill") + theme(legend.position = "bottom") + guides(fill = guide_legend(nrow = 1))

ggplot2: doughnuts, how to conditional color fill with if_else

Following guides like ggplot Donut chart I am trying to draw small gauges, doughnuts with a label in the middle, with the intention to put them later on on a map.
If the value reaches a certain threshold I would like the fill of the doughnut to change to red. Is it possible to achieve with if_else (it would be most natural but it does not work).
library(tidyverse)
df <- tibble(ID=c("A","B"),value=c(0.7,0.5)) %>% gather(key = cat,value = val,-ID)
ggplot(df, aes(x = val, fill = cat)) + scale_fill_manual(aes,values = c("red", "yellow"))+
geom_bar(position="fill") + coord_polar(start = 0, theta="y")
ymax <- max(df$val)
ymin <- min(df$val)
p2 = ggplot(df, aes(fill=cat, y=0, ymax=1, ymin=val, xmax=4, xmin=3)) +
geom_rect(colour="black",stat = "identity") +
scale_fill_manual(values = if_else (val > 0.5, "red", "black")) +
geom_text( aes(x=0, y=0, label= scales::percent (1-val)), position = position_dodge(0.9))+
coord_polar(theta="y") +
xlim(c(0, 4)) +
theme_void() +
theme(legend.position="none") +
scale_y_reverse() + facet_wrap(facets = "ID")
Scale fill manual values= if else.... this part does not work, the error says: Error in if_else(val > 0.5, "red", "black") : object 'val' not found. Is it my error, or some other solution exists?
I also realize my code is not optimal, initially gather waited for more variables to be included in the plot, but I failed to stack one variable on top of the other. Now one variable should be enough to indicate the percentage of completion. I realise my code is redundant for the purpose. Can you help me out?
A solution for the color problem is to first create a variable in the data and then use that to map the color in the plot:
df <- tibble(ID=c("A","B"),value=c(0.7,0.5)) %>% gather(key = cat,value = val,-ID) %>%
mutate(color = if_else(val > 0.5, "red", "black"))
p2 = ggplot(df, aes(fill=color, y=0, ymax=1, ymin=val, xmax=4, xmin=3)) +
geom_rect(colour="black",stat = "identity") +
scale_fill_manual(values = c(`red` = "red", `black` = "black")) +
geom_text( aes(x=0, y=0, label= scales::percent (1-val)), position = position_dodge(0.9))+
coord_polar(theta="y") +
xlim(c(0, 4)) +
theme_void() +
theme(legend.position="none") +
scale_y_reverse() + facet_wrap(facets = "ID")
The result would be:

Resources