Moving legend to the bottom in ggplot2 [duplicate] - r

This question already has answers here:
How to move or position a legend in ggplot2
(4 answers)
Closed 7 years ago.
I have created the following heatmap. If you notice that the legend for cohort is on the right and the vertically placed.
How do I move the legend to the bottom in order to give more space for X axis variable month M0 to M55...Also, you will notice that X axis elements are overlapping hence not clear.
Output of the graph:
cohort.clients<-df1
cohort.clients$cohort<-as.character(cohort.clients$cohort)
#we need to melt data
cohort.chart.cl <- melt(cohort.clients, id.vars = 'cohort')
colnames(cohort.chart.cl) <- c('cohort', 'month', 'clients')
#define palette
reds <- colorRampPalette(c('light green',"dark green","yellow"))
#plot data
p <- ggplot(cohort.chart.cl, aes(x=month, y=clients, group=cohort))
p + geom_area(aes(fill = cohort)) +
scale_fill_manual(values = reds(nrow(cohort.clients))) +
ggtitle('Customer Cohort')

Try something like:
ggplot(cohort.chart.cl, aes(x=month, y=clients, group=cohort))
geom_area(aes(fill = cohort)) +
scale_fill_manual(values = reds(nrow(cohort.clients))) +
ggtitle('Customer Cohort') +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
legend.direction = "horizontal", legend.position = "bottom"))
It's also worth noting that your color palette is essentially the same color. If you make cohort$month a factor then ggplot should automatically give you a much more informative palette by default. That being said, with >50 categories, you're well past the realm of a distinguishable colors and might also consider binning the months (into yearly quarters?) and returning to a spectrum like you have now.

Related

move y axis labels closer to heatmap (ggplot2) [duplicate]

This question already has answers here:
Remove space between plotted data and the axes
(3 answers)
Closed 1 year ago.
I am trying to move my y-axis tick marks closer to my heatmap.
Here is the code for the heatmap:
ggplot(p_typ_meta, aes(SampleType_Basic, Phylum, fill= Counts)) +geom_tile()+
scale_fill_gradient2(low="blue", mid="white",high="red",midpoint=.15)+theme(axis.title.x = element_text(size=13),axis.title.y = element_text(size=13),axis.text = element_text(size=11),axis.text.y=element_text(margin = margin(0,0)),legend.title.align=0.5, legend.title = element_text(size=13),legend.text = element_text(size=11),plot.title = element_text(hjust=0.5, size=15)) +labs(x="Sample Type", y="Microbial Phyla", title="Microbial Phyla & Sample Type",fill="Relative Abundance")+theme_classic()
I have tried the following:
theme(axis.text.y=element_text(hjust=0.5))
theme(axis.text.y=element_text(margin = margin(0,0)))
theme(axis.ticks.margin=unit(0,'cm'))
theme(axis.text.y = element_text(margin = margin(r = 0)))
scale_y_discrete(expand = c(0, 0))
scale_y_continuous(expand=c(0, 0))
Is there something I am missing in my code? Or is this just how heatmaps work in ggplot2?
I have attached the heatmap I made, and the red arrows show where I want to move the y axis labels. Thanks for the insight!
Using scale_x_discrete(expand = c(0,0)) does the trick. Since you want to reduce the space on the x-axis you need to use this scale and not the one for the y axis.

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

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)

Adding different secondary x axis for each facet in ggplot2

I would like to add a different secondary axis to each facet. Here is my working example:
library(ggplot2)
library(data.table)
#Create the data:
data<-data.table(cohort=sample(c(1946,1947,1948),10000,replace=TRUE),
works=sample(c(0,1),10000,replace=TRUE),
year=sample(seq(2006,2013),10000,replace=TRUE))
data[,age_cohort:=year-cohort]
data[,prop_works:=mean(works),by=c("cohort","year")]
#Prepare data for plotting:
data_to_plot<-unique(data,by=c("cohort","year"))
#Plot what I want:
ggplot(data_to_plot,aes(x=age_cohort,y=prop_works))+geom_point()+geom_line()+
facet_wrap(~ cohort)
The plot shows how many people of a particular cohort work at a given age. I would like to add a secondary x axis showing which year corresponds to a particular age for different cohorts.
Since you have the actual values you want to use in your dataset, one work around is to plot them as an additional geom_text layer:
ggplot(data_to_plot,
aes(x = age_cohort, y = prop_works, label = year))+
geom_point() +
geom_line() +
geom_text(aes(y = min(prop_works)),
hjust = 1.5, angle = 90) + # rotate to save space
expand_limits(y = 0.44) +
scale_x_continuous(breaks = seq(58, 70, 1)) + # ensure x-axis breaks are at whole numbers
scale_y_continuous(labels = scales::percent) +
facet_wrap(~ cohort, scales = "free_x") + # show only relevant age cohorts in each facet
theme(panel.grid.minor.x = element_blank()) # hide minor grid lines for cleaner look
You can adjust the hjust value in geom_text() and y value in expand_limits() for a reasonable look, depending on your desired output's dimensions.
(More data wrangling would be required if there are missing years in the data, but I assume that isn't the case here.)

R ggplot remove certain items from legend [duplicate]

This question already has answers here:
Turning off some legends in a ggplot
(2 answers)
Closed 4 years ago.
Is it possible to remove certain items from a legend created with ggplot? I have a plot that is faceted, and point sizes provide another dimension to the plot. Since the plot is faceted I do not need to have certain legend items since it is explained by the facet titles, but the legend is still relevant for the point size.
In the plot below I would like to remove the "AREA" legend items since it is already explained by the faceting, but keep the "TOTAL_VOLUME" legend items that explain the point sizes.
Here is the code used to generate the plot:
library(data.table) # Import libraries
library(ggplot2)
library(scales)
set.seed(1234) # Set Seed
area.list <- LETTERS[seq(1:7)] # 7 Possible areas
date.list <- seq(as.Date("2014/03/01"), by="month", length=13)
# Build a random data set
data <- data.table(AREA = sample(area.list, 80, replace=TRUE),
DATE = sample(date.list, 80, replace=TRUE),
VOLUME = rnorm(n=80, mean=100000,sd=40000),
NON_CONFORMING_VOLUME = rnorm(n=80, mean=30000,sd=5000))
# Summarise data by area and date
data <- data[, list(TOTAL_VOLUME=sum(VOLUME),
TOTAL_NC_VOLUME=sum(NON_CONFORMING_VOLUME)),
by=list(AREA, DATE)]
data$PERCENT_NC <- data$TOTAL_NC_VOLUME / data$TOTAL_VOLUME * 100
p <- ggplot(data = data, aes(x = DATE,
y = PERCENT_NC,
colour = AREA)) +
geom_point(aes(size = TOTAL_VOLUME)) +
geom_line() +
facet_grid(. ~ AREA) +
theme(legend.position="bottom", axis.text.x=element_text(angle=90,hjust=1)) +
ggtitle("Percent Non-Conforming by Area by Month") +
labs(x = "Month", y = "% Non-Conforming") +
scale_size_continuous(labels = comma)
plot(p)
I tried adding show_guide=FALSE to geom_point() but that removes both TOTAL_VOLUME and AREA.
Thank you
You can set the guide for each scale in the following way:
p + guides(size = "legend", colour = "none")

Put labels on pie ggplot2 [duplicate]

This question already has answers here:
ggplot, facet, piechart: placing text in the middle of pie chart slices
(4 answers)
Closed 7 years ago.
My df looks like:
1 with score
125 without score
I'd like to make piechart in ggplot:
ggplot(data = df_pp, aes(x = "", y = Number/sum(Number),fill = PolyPhen_score)) + geom_bar(stat="identity") + coord_polar(theta='y') +
ggtitle("Variants with PolyPhen score and without PolyPhen score") +
scale_y_continuous(labels = percent) + labs(x = "", y = "") +
theme(panel.background = element_rect(fill = 'white')) +
geom_text(aes(label = paste(round(Number/sum(Number)*100),"%")),vjust = 5)
But my labels 1% and 99% are overlapped on the piechart.
If I add this code, it doesn't help:
geom_text(aes(y=Number/2 + c(0,cumsum(Number)[-length(Number)]), label = percent(Number/100)), size=5)
Maybe these other Stackoverflow questions can help you:
ggplot, facet, piechart: placing text in the middle of piechart slices
R + ggplot2 => add labels on facet pie chart
I did few tests on my machine with some random data and I tried with this:
geom_text(aes(x = 1.7, y=cumsum(Number/sum(Number)) - Number/sum(Number)/2, label = paste(round(Number/sum(Number)*100),"%")), size = 6)
X is the distance of labels from the center of the pie. x = 1.7 gives me a nice result with my data in RStudio, but probably you will need different values.

Resources