Reverse color palette with legend limits ggplot2 - r

I have a set of polygons, an reproducable example here from code in this question:
# polygons
square <- t(replicate(8, {
o <- runif(2)
c(o, o + c(0, 0.1), o + 0.1, o + c(0.1, 0), o)
}))
ID <- paste0('sq', seq_len(nrow(square)))
# Create SP
polys <- SpatialPolygons(mapply(function(poly, id) {
xy <- matrix(poly, ncol=2, byrow=TRUE)
Polygons(list(Polygon(xy)), ID=id)
}, split(square, row(square)), ID))
# Create SPDF and add a column for values
polys.df <- SpatialPolygonsDataFrame(polys, data.frame(id=ID, row.names=ID))
polys.df#data$number <- c(1,2,3,4,5,6,7,8)
I then want to plot these with a single color palette, but want the highest numbers to be dark rather than light as in the default. After fortifying to use ggplot
f.polys = fortify(polys.df, region='id')
f.polys = merge(f.polys, polys.df#data, by.x='id', by.y='id')
I attempted to plot using a couple scale_fill_distiller options. So, this code works to set legend bar limits but doesn't reverse the palette:
ggplot() +
geom_polygon(data = f.polys, aes(x = long, y = lat, fill=number, group = group), color = 'black') +
scale_fill_distiller(palette = "Oranges", limits = c(0,10), breaks=c(0,2,8))
And this code reverses the palette, without being able to assign limits and breaks:
ggplot() +
geom_polygon(data = f.polys, aes(x = long, y = lat, fill=number, group = group), color = 'black') +
scale_fill_distiller(palette = "Oranges", trans = 'reverse')
When I try to combine the scale_fill_distiller arguments the palette does not reverse and I lose the scale bar. Any recommendations?
ggplot() +
geom_polygon(data = f.polys, aes(x = long, y = lat, fill=number, group = group), color = 'black') +
scale_fill_distiller(palette = "Oranges", trans = 'reverse',limits = c(0,10), breaks=c(0,2,8))

You need to switch your limits around so the range goes from high to low instead of low to high. This then matches the reversing of the scale and the legend gets drawn.
scale_fill_distiller(palette = "Oranges", trans = "reverse",
limits = c(10,0), breaks=c(0,2,8))

Related

ggplot2 palette legend does not show

I just started using ggplot2 R package and the following question should be very trivial, however I spent 2h on it without success.
I just need to show the scale_fill_distiller legend of the RdBu palette from -1 to 1 (red to blue) on my ggplot.
Here's a code example:
## Load ggplot2 package
require(ggplot2)
## Create data.frame for 4 countries
shape = map_data("world") %>%
filter(region == "Germany" | region == 'Italy' | region == 'France' | region == 'UK')
## Order data.frame by country name
shape = shape[with(shape, order(region)), ]
rownames(shape) = NULL # remove rownames
##### Assign 4 different values (between -1 and 1) to each country by creating a new column 'id'
## These will be the values to be plotted with ggplot2 palette
shape[c(1:605),'id'] = 0.2
shape[c(606:1173),'id'] = -0.4
shape[c(1174:1774),'id'] = -0.9
shape[c(1775:2764),'id'] = 0.7
##### Make plot
ggplot() +
## plot countries borders
geom_polygon(data = shape, aes(x = long, y = lat, group = group, fill = id), colour = 'black') +
## adjust coordinates
coord_map() +
## remove any background
ggthemes::theme_map() +
## add colour palette
scale_fill_distiller(palette = 'RdBu', limits = c(1, -1), breaks = 50)
The legend of the RdBu palette should pop out automatically but here it doesn't. Is there any layer that is masking it?
OR
Is there any way to create a new legend from scratch and add it to the above plot?
I need something like the picture below, but from -1 to 1 (Red to Blue) and vertical:
Thanks
The range specified in limits should be c(min, max) and not c(max, min):
this works as expected:
library(ggmap)
library(ggplot2)
library(ggthemes)
ggplot() +
geom_polygon(data = shape,
aes(x = long, y = lat, group = group, fill = id), colour = 'black') +
coord_map() +
ggthemes::theme_map() +
scale_fill_distiller(palette = 'RdBu', limits = c(-1,1))
while limits = c(1, -1) produces a plot without a colorbar:
ggplot() +
geom_polygon(data = shape,
aes(x = long, y = lat, group = group, fill = id), colour = 'black') +
coord_map() +
ggthemes::theme_map() +
scale_fill_distiller(palette = 'RdBu', limits = c(1, -1))
If you would like to map the values in reverse order, you can use the direction argument:
ggplot() +
geom_polygon(data = shape,
aes(x = long, y = lat, group = group, fill = id), colour = 'black') +
coord_map() +
ggthemes::theme_map() +
scale_fill_distiller(palette = "RdBu",
limits = c(-1, 1),
breaks = c(-1, 0, 1),
direction = 1)

Recentering state abbreviation on ggplot2

So I modified the shape profile to add Hawaii and Alaska and so my data frame is using a different long, lat coordinates than the stock state coordinates provided by maps package (map_data("state")) shown below
states <- data.frame(state.center, state.abb)
states
x y state.abb
1 -86.7509 32.5901 AL
2 -127.2500 49.2500 AK
3 -111.6250 34.2192 AZ
4 -92.2992 34.7336 AR
5 -119.7730 36.5341 CA
My data frame have coordinates as follow.
When I plot it using the code below I get a map without any state abbreviation labels.
p <- function(data, brks, title) {
ggp <- ggplot() +
geom_polygon(data = data, aes(x = long, y = lat, group = group,
fill = IMSUB), color = "black", size = 0.15) +
scale_fill_gradient2(limits=c(-1,1), breaks = c(-1, 0, 1), labels=c("Trump", 0, "Clinton"), low = "red", mid = "white",
high = "blue", midpoint = 0, space = "Lab",
na.value = "grey50", guide = "colourbar") +
theme_nothing(legend = TRUE) + labs(title = title, fill = "") +
geom_text(data = states, aes(x = x, y = y, label = state.abb), size = 3)
return(ggp)
}
i feel like I can replace the coordinates in states data frame with one in us50 but I am not sure how to replace them correctly.
Did you try it with the size inside the aes()?
geom_text(data=state, aes(x y, label = state.abb, size=3)
If not, this other method will likely work instead, just replace the geom_text line:
with(states, annotate(geom="text", x = x y=y, label = state.abb, size = 3))
It should apply annotation using states, as text with x & y as your lat and long..That should work.

distill colors of polygons on a map with ggplot2

I'm trying to plot the different ways to name a pencil in France on a map with ggplot2. For each of the 96 departments of France, I have one item and a score associated to this item. I have no problem plotting the items according to their departments on a map, but I can't figure out a way to make the colors of each polygons vary according to their associated score. My data is here. The code to produce the map is below:
library(ggplot2)
library(scales)
library(Cairo)
#open data
plotDatafr = read.table("plotDatafr.txt", header=T, sep="\t", quote="", dec=".")
g <- ggplot() +
geom_polygon(data = plotDatafr, aes(x=long, y = lat, group = group, fill=item), alpha=0.8, colour = "black") +
scale_fill_manual(values = c("#009E73", "#F0E442", "#0072B2", "#D55E00"), na.value=NA) +
theme_nothing(legend = TRUE) +
coord_map() #avoid distorsion
ggsave(g, filename = "crayon_euro.png", scale=1) #save for futher use
I tried to use the "scale_fill_distiller" command, but with such command I can only plot the properties of a single item, and I loose their given colors, for example:
g <- ggplot() +
geom_polygon(data = plotDatafr, aes(x = long, y = lat, group = group, fill = score), colour = "black", alpha = 0.8) +
scale_fill_distiller(palette = "Purples", breaks = pretty_breaks(n = 9), labels = percent, direction = 1, "", guide=FALSE) +
guides(fill = guide_legend(reverse = TRUE, override.aes = list(alpha = 1))) +
theme_nothing(legend = TRUE) +
coord_map() #avoid distorsion
ggsave(g, filename = "crayon_euro.png", scale=1) #save for futher use
Does anyone have any idea how I can make the different my polygons shades varying according to their numerical value? I can't figure a way to combine scale_fill_distiller and scale_fill_manual in the same time.
you could use scale_fill_gradient instead to adjust aes(fill) by plotDatafr$score:
#open plotting data
plotDatafr = read.table("plotDatafr.txt", header=T, sep="\t", quote="", dec=".")
# make mapping data object
fr <- map_data("france")
# plot
ggplot(fr, aes(x=long, y = lat, group = group)) +
geom_polygon(data = plotDatafr, aes(fill=score), alpha=0.8, colour = "black") +
scale_fill_gradient(low = "yellow", high = "blue", na.value=NA) +
coord_map()
scale_fill_distiller is designed for discrete data, so you would have to bin plotDatafr$score in some way, before using it.
The answer given by #Haboryme above works perfectly! The trick is to set the alpha with "score" directly in the aes() of geom_polygon, that is to say:
ggplot() + geom_polygon(data = plotDatafr, aes(x = long, y = lat, group = group, fill = item, alpha = score), colour = NA) + scale_fill_manual(values = c("#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7"), name = "", na.value=NA) + coord_map()

Have separate legends for a set of point-line plots, and a vertical line plot

Example data frame (if there's a better/more idiomatic way to do this, let me know):
n <- 10
group <- rep(c("A","B","C"),each = n)
x <- rep(seq(0,1,length = n),3)
y <- ifelse(group == "A",1+x,ifelse(group == "B",2+2*x,3+3*x))
df <- data.frame(group,x,y)
xd <- 0.5
des <- data.frame(xd)
I want to plot create point-line plots for the data in df, add a vertical curve at the x location indicated by xd, and get readable legends for both. I tried the following:
p <- ggplot(data = df, aes(x = x, y = y, color = group)) + geom_point() + geom_line(aes(linetype=group))
p <- p + geom_vline(data = des, aes(xintercept = xd), color = "blue")
p
Not quite what I had in mind, there's no legend for the vertical line.
A small modification (I don't understand why geom_vline is one of the few geometries with a show.legend parameter, which moreover defaults to FALSE!):
p <- ggplot(data = df, aes(x = x, y = y, color = group)) + geom_point() + geom_line(aes(linetype=group))
p <- p + geom_vline(data = des, aes(xintercept = xd), color = "blue", show.legend = TRUE)
p
At least now the vertical bar is showing in the legend, but I don't want it to go in the same "category" (?) as group. I would like another legend entry, titled Design, and containing only the vertical line. How can I achieve this?
A possible approach is to add an extra dummy aesthetic like fill =, which we'll subsequently use to create the second legend in combination with scale_fill_manual() :
ggplot(data = df, aes(x = x, y = y, color = group)) +
geom_point() +
geom_line(aes(linetype=group), show.legend = TRUE) +
geom_vline(data = des,
aes(xintercept = xd, fill = "Vertical Line"), # add dummy fill
colour = "blue") +
scale_fill_manual(values = 1, "Design", # customize second legend
guide = guide_legend(override.aes = list(colour = c("blue"))))

Legend units for geom_point size

I have used geom_point in ggplot2 to display values as the area of each point:
geom_point(aes(size = sqrt(z/pi))
However, the legend units are the transformed values, is it possible to have the legend display the original values alongside their respective bubble size?
Edit: sorry I should have provided more information to begin with
library(ggplot2)
data <- data.frame(x = sample(1:10), y = sample(1:10), z = sample(1:10), colour = c("red", "yellow", "green","pink","black","brown","grey","white","purple","beige"))
ggplot(data, aes(x = x, y = y)) + geom_point(aes(size = sqrt(z/pi)), pch = 21) + aes(fill = colour) + scale_fill_brewer(palette = "set1")
Try adding:
+scale_colour_manual(guide = guide_legend(override.aes=aes(size=values)))

Resources