Legend does not fit well ggplot density - r

I am doing a plot of densities, I want to add a legend but is overlapped with the symbol. The code is hereunder:
dfGamma = data.frame(a = rgamma(100,shape = 7.1,rate= 0.0055),
b = rgamma(100, shape = 10,rate= 0.0055),
c = rgamma(100, shape = 7.1,rate= 0.0055))
dfGamma = stack(dfGamma)
p <- ggplot(dfGamma, aes(x = values)) +
stat_density(aes(group = ind, colour = ind),position="identity",geom="line",size=1)+
ggtitle("Gamma distribution")+theme(legend.position="right")+
scale_color_manual(labels = c(expression(paste(alpha,"=7.1 ",beta,"=0.0055")),
expression(paste(alpha,"= 10 ",beta,"=0.0055")),
expression(paste(alpha,"=7.1 ",beta,"=0.0055"))),
values = c('red', 'blue',"green"))
p
the plot is:

The guides option, guide_legend is what you need. You can read more about it in the ggplot reference. Does this help?
p <- ggplot(dfGamma, aes(x = values)) +
stat_density(aes(group = ind, colour = ind),position="identity",geom="line",size=1)+
ggtitle("Gamma distribution")+
theme(legend.position="right") +
scale_color_manual(labels = c(expression(paste(alpha, "=7.1 ", beta, "=0.0055")),
expression(paste(alpha,"= 10 ",beta,"=0.0055")),
expression(paste(alpha,"=7.1 ",beta,"=0.0055"))),
values = c('red', 'blue',"green")) +
guides(colour = guide_legend(label.position = "bottom"))
p

Related

How to color the area between two geom_smooth lines?

I have 3 columns in a data frame from which I want to create a visualisation with geom_smooth() :
ggplot(my_data_frame) +
aes(x = fin_enquete,
y = intentions,
colour = candidat) +
geom_point(alpha = 1/6,
shape = "circle",
size = .5L) +
geom_smooth(mapping = aes(y = erreur_inf),
size = .5L,
span = .42,
se = F) +
geom_smooth(mapping = aes(y = erreur_sup),
size = .5L,
span = .42,
se = F) +
geom_smooth(method = "loess",
size = 1.5L,
span = .42,
se = F) +
labs(x = "Date de fin d'enquĂȘte",
y = "Pourcentage d'intentions de vote") +
theme_minimal() +
theme(text = element_text(family = "DIN Pro")) +
coord_cartesian(expand = F) +
easy_remove_legend()
3 lines with geom_smooth
I would like to color the area between the upper and the lower line. I know the geom_ribbon() function but I am not sure I can use it in this situation.
Does anybody have a solution?
Have a nice day!
You could use geom_ribbon and calculate the loess model yourself within the geom_ribbon call?
Toy random data
dat <- data.frame(x=1:100, y=runif(100), y2=runif(100)+1, y3=runif(100)+2)
Now suppose we want a smoothed ribbon between y and y3, with y2 drawn as a line between them:
ggplot( dat , aes(x, y2)) +
geom_ribbon(aes(ymin=predict(loess(y~x)),
ymax=predict(loess(y3~x))), alpha=0.3) +
geom_smooth(se=F)
You could use lapply() smooth to calculate the range of df values such as (5,11,13) to calculate the smooths and plot only the two edges of the se.
Sample code:
library(ggplot2)
ggplot(data = mtcars,
mapping = aes(x = wt,
y = mpg)) +
geom_point(size = 2)+
lapply(c(5,11, 13), function (i) {
geom_smooth(
data = ~ cbind(., facet_plots = i),
method = lm,
se=F,
formula = y ~ splines::bs(x, i)
)
})+
#facet_wrap(vars(facet_plots))
geom_ribbon(
stat = "smooth",
method = "loess",
se = TRUE,
alpha = 0, # or, use fill = NA
colour = "black",
linetype = "dotted")+
theme_minimal()
Plot:

Swap key and label in ggplot legend

I have a plot like this:
library("ggplot2")
library("ggtext")
df = data.frame(x = rnorm(n=12), y = rnorm(n=12),
groupshape = rep(c("a","b","c"), 4),
groupcol = rep(c("e","d","f"), 4))
p = ggplot(df, aes(x = x,y = y,
shape = groupshape,
color = groupcol)) +
geom_point() + theme_classic() + labs(shape = "shape", color = "color")
Producing a plot like this:
But I want to know how to get something like this with the legend:
How would I do that? I can get rid of the shape itself through guides by turning them all while, but then the text just hovers menacingly without alignment to the legend below.
This could be achieved via the label.position and the label.theme arguments of guide_legend:
library("ggplot2")
library("ggtext")
df = data.frame(x = rnorm(n=12), y = rnorm(n=12),
groupshape = rep(c("a","b","c"), 4),
groupcol = rep(c("e","d","f"), 4))
ggplot(df, aes(x = x,y = y,
shape = groupshape,
color = groupcol)) +
geom_point() + theme_classic() + labs(shape = "shape", color = "color") +
guides(color = guide_legend(label.position = "left", label.theme = element_text(face = "bold")),
shape = guide_legend(label.position = "left"))

adding a label in geom_line in R

I have two very similar plots, which have two y-axis - a bar plot and a line plot:
code:
sec_plot <- ggplot(data, aes_string (x = year, group = 1)) +
geom_col(aes_string(y = frequency), fill = "orange", alpha = 0.5) +
geom_line(aes(y = severity))
However, there are no labels. I want to get a label for the barplot as well as a label for the line plot, something like:
How can I add the labels to the plot, if there is only pone single group? is there a way to specify this manually? Until know I have only found option where the labels can be added by specifying them in the aes
EXTENSION (added a posterior):
getSecPlot <- function(data, xvar, yvar, yvarsec, groupvar){
if ("agegroup" %in% xvar) xvar <- get("agegroup")
# data <- data[, startYear:= as.numeric(startYear)]
data <- data[!claims == 0][, ':=' (scaled = get(yvarsec) * max(get(yvar))/max(get(yvarsec)),
param = max(get(yvar))/max(get(yvarsec)))]
param <- data[1, param] # important, otherwise not found in ggplot
sec_plot <- ggplot(data, aes_string (x = xvar, group = groupvar)) +
geom_col(aes_string(y = yvar, fill = groupvar, alpha = 0.5), position = "dodge") +
geom_line(aes(y = scaled, color = gender)) +
scale_y_continuous(sec.axis = sec_axis(~./(param), name = paste0("average ", yvarsec),labels = function(x) format(x, big.mark = " ", scientific = FALSE))) +
labs(y = paste0("total ", yvar)) +
scale_alpha(guide = 'none') +
theme_pubclean() +
theme(legend.title=element_blank(), legend.background = element_rect(fill = "white"))
}
plot.ExposureYearly <- getSecPlot(freqSevDataAge, xvar = "agegroup", yvar = "exposure", yvarsec = "frequency", groupvar = "gender")
plot.ExposureYearly
How can the same be done on a plot where both the line plot as well as the bar plot are separated by gender?
Here is a possible solution. The method I used was to move the color and fill inside the aes and then use scale_*_identity to create and format the legends.
Also, I needed to add a scaling factor for severity axis since ggplot does not handle the secondary axis well.
data<-data.frame(year= 2000:2005, frequency=3:8, severity=as.integer(runif(6, 4000, 8000)))
library(ggplot2)
library(scales)
sec_plot <- ggplot(data, aes(x = year)) +
geom_col(aes(y = frequency, fill = "orange"), alpha = 0.6) +
geom_line(aes(y = severity/1000, color = "black")) +
scale_fill_identity(guide = "legend", label="Claim frequency (Number of paid claims per 100 Insured exposure)", name=NULL) +
scale_color_identity(guide = "legend", label="Claim Severity (Average insurance payment per claim)", name=NULL) +
theme(legend.position = "bottom") +
scale_y_continuous(sec.axis =sec_axis( ~ . *1, labels = label_dollar(scale=1000), name="Severity") ) + #formats the 2nd axis
guides(fill = guide_legend(order = 1), color = guide_legend(order = 2)) #control which scale plots first
sec_plot

guide_legend and ggplot2, format nrow

I am trying to format an over-long legend on a ggplot so that there is a maximum no. of rows. I've read all the documentation that I could find, especially this: http://docs.ggplot2.org/0.9.3.1/guide_legend.html but for some reason, the legend will not format.
I've given a reproducible sample below using the quakes dataset, and converted the column stations to character so that they plot individually (otherwise, they seem to plot as groups).
plotquakes <- function(magreq) {
library(ggplot2)
magdata <- subset(quakes, mag > magreq)
magdata$stations <- as.character(magdata$stations)
g <- ggplot(magdata, aes (x = lat, y = long))
g + geom_point(aes(alpha = stations), fill = "black", pch=21, size = 6) +
labs(x = "Latitude", y = "Longitude") +
geom_vline(xintercept = 0, col = "red") +
geom_hline(yintercept = 0, col = "red") +
guides(col = guide_legend(nrow = 16))
}
plotquakes(5)
And what I get is this:
whereas I would like to have a maximum of 16 data fields per column in the legend.
You are changing the wrong guide.
plotquakes <- function(magreq) {
library(ggplot2)
magdata <- subset(quakes, mag > magreq)
magdata$stations <- as.character(magdata$stations)
g <- ggplot(magdata, aes (x = lat, y = long))
g + geom_point(aes(alpha = stations), fill = "black", pch=21, size = 6) +
labs(x = "Latitude", y = "Longitude") +
geom_vline(xintercept = 0, col = "red") +
geom_hline(yintercept = 0, col = "red") +
guides(alpha = guide_legend(nrow = 16)) #note it's alpha not col
}
plotquakes(5)

ggplot2 legend with two different geom_point

I have the following ggplot graph with circles representing the observed data and the crosses the mean for each treatment :
d <- data.frame(Number = rnorm(12,100,20),
Treatment = rep(c("A","B","C", "D"), each = 3))
av <- aggregate(d["Number"], d["Treatment"], mean)
ggplot(data = d, aes(y = Number, x = Treatment)) +
geom_point(shape = 1, size = 6, color = "grey50") +
geom_point(data=av, shape = 4) +
theme_bw()
I would like to add a legend with the exact same symbols on top of the graphs but I'm a bit lost... I use aes to force the creation of legend and then try to modify it with manual scales but the result is not convincing. I would like to have one grey circle of size 6. That sounds also quite complicated for such a basic thing ... There is probably an easyier solution.
ggplot(data = d, aes(y = Number, x = Treatment)) +
geom_point(aes(shape = "1", size = "6", color = "grey50")) +
geom_point(data=av, aes(shape = "4")) +
theme_bw() +
scale_shape_manual(name = "", values = c(1,4), labels = c("observed values", "mean")) +
scale_size_manual(name = "", values = c(6,1), labels = c("observed values", "mean")) +
scale_color_manual(name = "", values = c("grey50","black"),
labels = c("observed values", "mean")) +
theme(legend.position = "top",
legend.key = element_rect(color = NA))
http://imagizer.imageshack.us/v2/320x240q90/842/4pgj.png
The ggplot2 way would be combining everything into a single data.frame like this:
av$Aggregated <- "mean"
d$Aggregated <- "observed value"
d <- rbind(d, av)
ggplot(data = d, aes(y = Number, x = Treatment,
shape=Aggregated, size=Aggregated, colour=Aggregated)) +
geom_point()
And than customize using manual scales and themes.

Resources