manually create ggplot legend when plot built from two data frames [duplicate] - r

This question already has answers here:
How to add legend to plot with data from multiple data frames
(2 answers)
Closed 2 years ago.
I am using ggplot to create two overlapping density from two different data frames. I need to create a legend for each of the densities.
I have been trying to follow these two posts, but still cannot get it to work:
How to add legend to plot with data from multiple data frames
ggplot legends when plot is built from two data frames
Sample code of what I am trying to do:
df1 = data.frame(x=rnorm(1000,0))
df2 = data.frame(y=rnorm(2500,0.5))
ggplot() +
geom_density(data=df1, aes(x=x), color='darkblue', fill='lightblue', alpha=0.5) +
geom_density(data=df2, aes(x=y), color='darkred', fill='indianred1', alpha=0.5) +
scale_color_manual('Legend Title', limits=c('x', 'y'), values = c('darkblue','darkred')) +
guides(colour = guide_legend(override.aes = list(pch = c(21, 21), fill = c('darkblue','darkred')))) +
theme(legend.position = 'bottom')
Is it possible to manually create a legend?
Or do I need to restructure the data as per this post?
Adding legend to ggplot made from multiple data frames with controlled colors
I'm newish to R so hoping to avoid stacking the data into a single dataframe if I can avoid it as they are weighted densities so have to multiply by different weights as well.

Unlike x, y, label etc., when using the density geom, the color aesthetic can be used within aes(). In order to accomplish what you are looking for, the color aesthetic needs to be moved into aes() enabling you to utilize scale_color_manual. Within that, you can change the values= to whatever you like.
library(tidyverse)
ggplot() +
geom_density(data=df1, aes(x=x, color='darkblue'), fill='lightblue', alpha=0.5) +
geom_density(data=df2, aes(x=y, color='darkred'), fill='indianred1', alpha=0.5) +
scale_color_manual('Legend Title', limits=c('x', 'y'), values = c('darkblue','darkred')) +
guides(colour = guide_legend(override.aes = list(pch = c(21, 21), fill = c('darkblue','darkred')))) +
theme(legend.position = 'bottom')+
scale_color_manual("Legend title", values = c("blue", "red"))
Created on 2020-08-09 by the reprex package (v0.3.0)

Related

How to seperate histogram plot into two facet with ggplot in r?

I want to separate my histogram into two parts and zoom the second part. In short, I want to keep the histogram in the original shape, just zoom the x-axis tail.
Using mpg dataset as an example, I create a facet label according to 'displ' column and create a histogram plot.
mpg$displn<-scale(mpg$displ)
mpg$myFacet<-"01"
mpg$myFacet[mpg$displn>1]<-"02"
library(ggh4x)
ggplot(mpg,aes(x=displn))+geom_histogram(aes(y=..density..),binwidth = 0.1)+ facet_grid(. ~ myFacet, scales="free", space="free") + scale_x_continuous(breaks = seq(-1.5, 2.5, 1)) + theme(strip.text.x = element_blank())+ theme(panel.spacing=unit(0,'npc')) +force_panelsizes(cols = c(0.3, 1))
The question is the two facets using different 'y=..density..' and looks different from the original figure.
Is there any suggestion on how should I improve this?
Thanks in advance!
Typically, one would use ggforce::facet_zoom() for this purpose:
library(ggplot2)
library(ggforce)
ggplot(mpg, aes(x = scale(displ))) +
geom_histogram(aes(y = after_stat(density)), binwidth = 0.1) +
facet_zoom(xlim = c(1, 3))
Created on 2022-01-13 by the reprex package (v2.0.1)
The reason your original approach doesn't work is because densities are calculated by group, and data belonging to different panels are automatically separated into different groups.

Duplicate legends in overlayed density plots using ggplot2

I am trying to generate density plot with two overlaid distributions using ggplot2. My data looks like:
diag_elements <- data.frame(x = c(diag(Am.dent), diag(Am.flint)),
group=rep(c("Dent", "Flint"), c(length(diag(Am.dent)), length(diag(Am.flint)))))
And my call to ggplot is:
ggplot(diag_elements) +
geom_density(aes(x=x, colour=group, fill=group), alpha=0.5) +
labs(x = "Diagonal elements of the matrix", y = "Density", fill = "Heterotic Group") +
theme(legend.position = c(0.85, .75))
However, instead of simply renaming the legend with the more complete name specified in fill, this generates a second legend:
Does anyone have any suggestions for getting this same graph, but without the improperly formatted legend?
Thanks!
The other option is guides which allows specific removal of certain legneds. You simply add to your ggplot
+guides(color=FALSE)

Add a custom legend to a ggplot with two geom_point layers using scale_..._manual

I have e.g two data sets first set contains the computation points and the second contains the grid coordinates. I want to plot them using ggplot and I want the legend to be as shown below:
The data
df1<- data.frame(lon=c(21:70), lat=c(64:113), tem=c(12:61)) # computation points data
df2<- data.frame(grd.lon=seq(21,70,3.5),grd.lat=seq(12,61, 3.5)) # grid points data
library(ggplot2)
ggplot()+geom_point(data=df1, aes(x=lon,y=lat), color="black", shape=20, size=3)+
geom_point(data=df2, aes(x=grd.lon, y=grd.lat), colour="red", shape=3)
I have seen similar questions but none of them really helped me
I tried also to plot the legend manually by add scale_color_manual and scale_shape_manaul, but still didn't work.
Any help please
Bind your df's in one, like so:
df3 <- list("computation point" = df1, "grid points" = df2) %>%
bind_rows(.id = "df")
Than map variables to aesthetics. ggplot2 will then automatically add a legend, which can be adjusted using scale_..._manual:
ggplot(df3, aes(shape = df, color = df)) +
geom_point(aes(x=lon,y=lat), size=3)+
geom_point(aes(x=grd.lon, y=grd.lat)) +
scale_shape_manual(values = c(20, 3)) +
scale_color_manual(values = c("black", "red")) +
labs(shape = NULL, color = NULL)

R, ggplot2: creating a single legend in a bubble chart with positive and negative values

I want to create a single legend for a bubble chart with positive and negative values like in plot below, generated using sp::bubble().
But, for various reasons I want to duplicate this in ggplot2. The closest I have gotten is to generate a single legend with scaled symbols, but the actual bubbles themselves are'nt scaled.
The above plot was created using the code below
# create data frame
x=sample(seq(1,50),50,T)
y=sample(seq(1,50),50,T)
plot_dat=data.frame(x=x,y=y,value=rnorm(50,0,25))
# plot
library(ggplot2)
ggplot(data=plot_dat, aes(x=x, y=y,colour=factor(sign(value)), size=value)) +
geom_point() +
scale_size(breaks = c(-40,-30,-20,-10,0,10,20,30,40,50), range = c(0.5,4)) +
scale_colour_manual(values = c("orange", "blue"), guide=F) +
guides(size = guide_legend(override.aes = list(colour = list("orange","orange","orange","orange","blue","blue","blue","blue","blue","blue"),size=c(3,2.5,2,1,0.5,1,2,2.5,3,4))))
Continue using abs(value) for size and sign(value) for color.
Provide the breaks= argument of scale_size_continuous() with duplicates of breaks required (e.g. c(10,10,20,20,...)). Next, provide labels= with the values you desire. Finally, use guides() and override.aes to set your own order of values and colours.
ggplot(data=plot_dat, aes(x=x, y=y,colour=factor(sign(value)), size=abs(value))) +
geom_point() +
scale_color_manual(values=c("orange","blue"),guide=FALSE)+
scale_size_continuous(breaks=c(10,10,20,20,30,30,40,40,50,50),labels=c(-50,-40,-30,-20,-10,10,20,30,40,50),range = c(1,5))+
guides(size = guide_legend(override.aes = list(colour = list("orange","orange","orange","orange","orange","blue","blue","blue","blue","blue"),
size=c(4.92,4.14,3.50,2.56,1.78,1.78,2.56,3.50,4.14,4.92))))
To assign exact values for the size= argument in the guides() function you could use function rescale() from the scales library. Rescale the entire range of values you are plotting, along with the break points provided to range= argument in scale_size_continuous().
set.seed(1234)
x=sample(seq(1,50),50,T)
y=sample(seq(1,50),50,T)
plot_dat=data.frame(x=x,y=y,value=rnorm(50,0,20))
library(scales)
rescale(c(abs(plot_dat$value),10,20,30,40,50),to=c(1,5))[51:55]
[1] 1.775906 2.562657 3.349409 4.136161 4.922912

Adding legends to multiple line plots with ggplot

I'm trying to add a legend to a plot that I've created using ggplot. I load the data in from two csv files, each of which has two columns of 8 rows (not including the header).
I construct a data frame from each file which include a cumulative total, so the dataframe has three columns of data (bv, bin_count and bin_cumulative), 8 rows in each column and every value is an integer.
The two data sets are then plotted as follows. The display is fine but I can't figure out how to add a legend to the resulting plot as it seems the ggplot object itself should have a data source but I'm not sure how to build one where there are multiple columns with the same name.
library(ggplot2)
i2d <- data.frame(bv=c(0,1,2,3,4,5,6,7), bin_count=c(0,0,0,2,1,2,2,3), bin_cumulative=cumsum(c(0,0,0,2,1,2,2,3)))
i1d <- data.frame(bv=c(0,1,2,3,4,5,6,7), bin_count=c(0,1,1,2,3,2,0,1), bin_cumulative=cumsum(c(0,1,1,2,3,2,0,1)))
c_data_plot <- ggplot() +
geom_line(data = i1d, aes(x=i1d$bv, y=i1d$bin_cumulative), size=2, color="turquoise") +
geom_point(data = i1d, aes(x=i1d$bv, y=i1d$bin_cumulative), color="royalblue1", size=3) +
geom_line(data = i2d, aes(x=i2d$bv, y=i2d$bin_cumulative), size=2, color="tan1") +
geom_point(data = i2d, aes(x=i2d$bv, y=i2d$bin_cumulative), color="royalblue3", size=3) +
scale_x_continuous(name="Brightness", breaks=seq(0,8,1)) +
scale_y_continuous(name="Count", breaks=seq(0,12,1)) +
ggtitle("Combine plot of BV cumulative counts")
c_data_plot
I'm fairly new to R and would much appreciate any help.
Per comments, I've edited the code to reproduce the dataset after it's loaded into the dataframes.
Regarding producing a single data frames, I'd welcome advice on how to achieve that - I'm still struggling with how data frames work.
First, we organize the data by combining i1d and i2d. I've added a column data which stores the name of the original dataset.
restructure data
i1d$data <- 'i1d'
i2d$data <- 'i2d'
i12d <- rbind.data.frame(i1d, i2d)
Then, we create the plot, using syntax that is more common to ggplot2:
create plot
ggplot(i12d, aes(x = bv, y = bin_cumulative))+
geom_line(aes(colour = data), size = 2)+
geom_point(colour = 'royalblue', size = 3)+
scale_x_continuous(name="Brightness", breaks=seq(0,8,1)) +
scale_y_continuous(name="Count", breaks=seq(0,12,1)) +
ggtitle("Combine plot of BV cumulative counts")+
theme_bw()
If we specify x and y within the ggplot function, we do not need to keep rewriting it in the various geoms we want to add to the plot. After the first three lines I copied and pasted what you had so that the formatting would match your expectation. I also added theme_bw, because I think it's more visually appealing. We also specify colour in aes using a variable (data) from our data.frame
If we want to take this a step further, we can use the scale_colour_manual function to specify the colors attributed to the different values of the data column in the data.frame i12d:
ggplot(i12d, aes(x = bv, y = bin_cumulative))+
geom_line(aes(colour = data), size = 2)+
geom_point(colour = 'royalblue', size = 3)+
scale_x_continuous(name="Brightness", breaks=seq(0,8,1)) +
scale_y_continuous(name="Count", breaks=seq(0,12,1)) +
ggtitle("Combine plot of BV cumulative counts")+
theme_bw()+
scale_colour_manual(values = c('i1d' = 'turquoise',
'i2d' = 'tan1'))

Resources