ggplot2: how to remove slash from geom_density legend - r

I'm trying to plot some overlapping density plots in ggplot2. I'm running into a problem where I cannot remove the diagonal slash from the legend. I have tried using scale_fill_manual() and legend.key as well as the hack from R Cookbook, but I cant seem to get it right.
data(iris)
iris=iris
cols=brewer.pal(3,"Set1")
ggplot(iris) +
geom_density(position="identity",aes(x=iris$Sepal.Length,fill=cols[1]),
colour="black",alpha=.5) +
geom_density(position="identity",aes(x=iris$Sepal.Width,fill=cols[2]),
colour="black",alpha=.5)+
theme_bw() +
scale_fill_identity(guide="legend",labels=c("Sepal Width","Sepal Length"))+
xlab("X axis") +
theme(panel.background=element_blank(),
legend.title=element_blank(),
legend.key = element_rect(),
legend.background = element_blank(),
legend.justification=c(1,0),
legend.position=c(.75,.5),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank())
What can I do to solve this?

Try this:
+ guides(fill = guide_legend(override.aes = list(colour = NULL)))
although that removes the black outline as well...which can be added back in by change the theme to:
legend.key = element_rect(colour = "black")
I completely forgot to add this important note: do not specify aesthetics via x=iris$Sepal.Length using the $ operator! That is not the intended way to use aes() and it will lead to errors and unexpected problems down the road.

Related

GGplot Error Continuous Scale Command errors

I am working on a homework assignment in R Studio and keep getting the Error: Discrete value supplied to continuous scale error. When doing this part: ggplot()+plot1+plot2+plot3 + coord_equal() + scale_fill_gradient( low="#473B31", high="#FFFFFF") I am not sure how to fix this Ive looked for seimilar solutions but cant find any that help me. Here is the full line of commands we are supposed to enter I highlighted where the issue was
# Create choropleth
plot1<- c(geom_polygon(data=LSOA_FF, aes(long, lat, group = group, fill = imd_rank)))
# Create road plot
plot2<-c(geom_path(data=roads_FF,aes(x=long, y=lat, group=group),size=0.1))
# Combine the plots
ggplot()+plot1+plot2+coord_equal()
We can add a further layer for the locations of the schools, and also adjust the color ramp.
# Create school plot
plot3 <- c(geom_point(data=schools, aes(Easting, Northing,colour='school')))
# Create combined plot
**ggplot()+plot1+plot2+plot3 + coord_equal() + scale_fill_gradient( low="#473B31", high="#FFFFFF")**
**#issue here**
It is also possible to control the other elements of the plot using "theme_bw()" which removes many of the visible elements.
#Create a clean plot
ggplot()+plot1+plot2+plot3 +coord_equal() + scale_fill_gradient( low="#473B31", high="#FFFFFF") + theme_bw()
However, the plot is still a little cluttered and we can turn off many of the elements using "theme()"
ggplot()+plot1+plot2+plot3 +coord_equal() + scale_fill_gradient( low="#473B31", high="#FFFFFF") + theme_bw() +
theme(axis.line = element_blank(),
axis.text = element_blank(),
axis.title=element_blank(),
axis.ticks = element_blank(),
legend.key = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank()) + labs(fill = "IMD Rank",colour="")

ggplot2: remove geom_tile wired top and bottom block

I tried to plot a matrix using geom_tile. However, I noticed there are two strange blocks appear at the top and bottom of my plot. My initial guess was these are ticks element. I've tried to specify the theme parameters as far as I know but no luck.
Basically, I want to remove the two wired blocks that I marked in red arrow. The left plot is something that I desired except the white block. The right plot is I tuned the plot.background in theme to show you there are something I don't know occupies the area.
Image here
I also attached the minimal code that could reproduce the left plot:
test2 <- matrix(runif(100*100),nrow = 100)
testdf <- test2 %>% reshape2::melt()
testdf$Var2 <- factor(testdf$Var2,levels=(seq(max(testdf$Var2),1))) # you could ignore this line
testdf %>% ggplot() + geom_tile(aes(x=Var2,y=Var1,fill=log2(value+1))) +
scale_fill_gradientn(colors = c("#ffffff","#f9c979","#ec8121","#b80217","#2f0006")) +
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.title = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
plot.background = element_blank()) + coord_equal()
These blocks are the result of ggplot2's default expansion of the scale. To get rid of these block set the expansion to zero via scale_y_continuous:
library(ggplot2)
library(reshape2)
test2 <- matrix(runif(100*100),nrow = 100)
testdf <- reshape2::melt(test2)
testdf$Var2 <- factor(testdf$Var2,levels=(seq(max(testdf$Var2),1))) # you could ignore this line
ggplot(testdf) +
geom_tile(aes(x=Var2,y=Var1,fill=log2(value+1))) +
scale_y_continuous(expand = c(0,0)) +
scale_fill_gradientn(colors = c("#ffffff","#f9c979","#ec8121","#b80217","#2f0006")) +
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.title = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
plot.background = element_blank()) + coord_equal()

ggplot legend labels and colors

I am struggling with ggplot to produce the legend of this figure. For now, I am only doing for one map, when it works I'l produce the four maps in the same plot.
I would like a legend like this: bottom, title in the center and above the scale, labels and colors, and omit the NA values.
Here is my code:
Reading the shapefile and installing a new variable
map_ev#data$id = rownames(map_ev#data)
map_ev.points = fortify(map_ev, region="id")
map_ev.df = join(map_ev.points, map_ev#data, by="id")
map_ev.df$median_norm = map_ev.df$median / map_ev.df$VOM
Vector with theme opts for ggplot
theme_opts <- list(theme(panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
panel.background = element_blank(),
panel.border = element_blank(),
axis.line = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
plot.title = element_text(size=12, hjust=0.5),
legend.position = "bottom",
legend.title=element_blank()))
Installing the variable breaks
map_ev.df$median_norm <- cut(map_ev.df$median_norm, breaks=c(-200, -100, -50, -20, -5, 0, 5, 20, 50, 100, +200))
Checking the breaks
levels(map_ev.df$median_norm)
Colors to be used
color_map <- palette(c("#5b2e07", "#904d07", "#b98436", "#dfc27e", "#f6e8c3",
"#c9e9e4", "#84cdc4", "#3c958f", "#01675a", "#073a31"))
ggplot code
ggplot(map_ev.df) +
aes(long,lat,group=group,fill=median_norm, color=median_norm) +
geom_polygon() + geom_path(color="black") +
labs(title="Equivalent variation") + coord_equal() +
theme_opts
For now I am getting this figure:
Thanks all, I appreciate your help!
I just noticed you wanted manual colours for the fill. You can use:
myscale <- c("(-1,10]"="#BBDF27", "(10,20]"="#43BF71", "(20,30]"="#21908C", "(30,50]"="#35608D", "(50,101]"="#482576", "(101,300]"="#ffeeed")
combined with:
scale_fill_manual(values=myscale,na.value="#e0e0e0",name="",labels=c("<10","10 - 20","20 - 30","30 - 50", ">50","Estimate", "NA"))
where scale_fill manual replaces scale_fill_brewer in the other answer.
Just replace the colour and label values with your own. The values that need to go into myscale are shown when you plot your map without any labels. Good luck!
The reason you don't have a title, is because you never specified one, and if you did, you're deleting it again by writing legend.title=element_blank() in theme. Instead I rewrote it to specify the title should be centered. Using guides(colour = guide_legend(title.position = "top"),fill = guide_legend(title.position = "top",nrow=1,byrow=TRUE)) I set the position to "top" and made sure it will only be one row of legend items. (I left colour= here in case you do need it).
You also seem to want black borders, this means I deleted all colour= since that specifies the colour of the borders.
I've added a scale_fill_brewer, there are more color palettes available. Within this you can specify your legend title and the appearance of your legend labels. These need to be manually adjusted every time you change your input data, by the way.
I don't know how to remove the legend item for NA, sorry.
This is the total code I came up with:
ggplot(map_ev.df) +
aes(long,lat,group=group,fill=median_norm) +
scale_fill_brewer(palette="BrBG",name= "Title of legend",labels=c("-200 - -100","-100 - 50","-5 - 0","0 - 5", "label for NA"))+
geom_polygon() + geom_path(color="black") +
labs(title="Equivalent variation") + coord_equal() +
theme(panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
panel.background = element_blank(),
panel.border = element_blank(),
axis.line = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
plot.title = element_text(size=12, hjust=0.5),
legend.position = "bottom",
legend.direction = "horizontal",
legend.title = element_text(hjust=0.5))+
guides(colour = guide_legend(title.position = "top"),fill = guide_legend(title.position = "top",nrow=1,byrow=TRUE))
Using some data of my own for the fill:
map

geom_errorbar and geom_facet

The following code does not display properly the error bars:
rf.imp<- read.csv("importances_byaggregations.csv",head=TRUE,sep=",") #Changes when handling the data
rf.imp$flux <- as.character(rf.imp$flux)
rf.imp$flux<-factor(rf.imp$flux,levels=unique(rf.imp$flux))
rf.imp$aggregation <- as.character(rf.imp$aggregation)
rf.imp$aggregation<-factor(rf.imp$aggregation,levels=unique(rf.imp$aggregation))
cbbPalette <- c("#F0E442", "#CC79A7","#E69F00","#56B4E9", "#009E73") # Mimicking Python colors
rf.imp$rel.influence<-rf.imp$rel.influence*100
rf.imp$SD<-rf.imp$SD*100
limits <- aes(ymax = rf.imp$rel.influence + rf.imp$SD, ymin=rf.imp$rel.influence - rf.imp$SD)
ggplot(rf.imp, aes(variable,rel.influence,fill=variable)) +
geom_bar(stat="identity",position="dodge") + scale_fill_manual(values=cbbPalette)+
theme_bw(base_size = 32, base_family = "Helvetica")+
xlab("")+
ylab("Variable importance (%)")+
facet_grid(aggregation~flux)+
geom_errorbar(limits, width=0.5)+
scale_y_continuous(limits=c(-10,90))+
theme(legend.position="none",
strip.text.x = element_blank(),
strip.text.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
strip.background = element_blank(),
panel.border = element_rect(colour = "black"),
panel.border = element_rect(colour = "black", fill=NA, size=1))
I would like to obtaine the following figure, but with the geom_facets swaped.
However, I get something like this:
Am I doing something wrong?
Thanks!
Your minimal example is a little too long for me to dig into, but I strongly suspect that your problem comes from using absolute (rf.imp$...) references in your error bar limits. If you use
geom_errorbar(aes(ymax=rel.influence+SD,
ymin=rel.influence-SD), width=0.5)
I think that will fix the problem.

how to correctly use guide_legend to control the number of rows of legend

I am ploting a figure in R with ggplot2. The legend in the figure has two rows but I want to unwrap them and make it in one row. I searched around and found that the guide_legned() is probably the way to go. I tried a couple of different ways and the only way does not give an error is like this:
fig <- ggplot(data, aes(y=y, x=x, shape=z))+
geom_point(size = 4)+
scale_shape_manual(values = c(0,1,2,3,4,6))+
geom_abline('somestuff in here')+
scale_fill_continuous(guide=guide_legend(nrow=1))+
annotate('somestuff in here')+
theme_bw()+
theme(legend.title = element_blank(),
panel.grid = element_blank(),
legend.position='top',
legend.key = element_blank())
However, the legend still turned out to be 2 rows. I am wondering why the guide_legend(nrow=1) is not working (even without an error). And what is the correct way to do it? Thanks!
You have a shape aesthetic, but no fill aesthetic in your plot, so scale_fill_continuous isn't applicable here. It's the shape legend you want to format. Two options:
fig <- ggplot(data, aes(y=y, x=x, shape=z))+
geom_point(size = 4)+
scale_shape_manual(values = c(0,1,2,3,4,6), guide=guide_legend(nrow=1)+
geom_abline('somestuff in here')+
annotate('somestuff in here')+
theme_bw()+
theme(legend.title = element_blank(),
panel.grid = element_blank(),
legend.position='top',
legend.key = element_blank())
fig <- ggplot(data, aes(y=y, x=x, shape=z))+
geom_point(size = 4)+
scale_shape_manual(values = c(0,1,2,3,4,6))+
geom_abline('somestuff in here')+
annotate('somestuff in here')+
theme_bw()+
theme(legend.title = element_blank(),
panel.grid = element_blank(),
legend.position='top',
legend.key = element_blank()) +
guides(shape=guide_legend(nrow=1))

Resources