Specifying the colour scale for maps in ggplot - r

Having difficulty setting the colour scales for maps in ggplot. I need greyscale. Very grateful for an idea where I'm going wrong. I also wonder if there is a more efficient way of getting the colour variable into ggplot (i.e. than by attaching it to 'fortified' data)?
library(ggplot2)
states <- map_data("state")
var <- data.frame(table(states$region)) # using rows as a dummy variable
states$variable <- var$Freq[match(states$region,var$Var1)]
map <- ggplot(states, aes(x=long, y=lat)) +
geom_polygon(aes(group=group, fill=variable), col=NA,lwd=0)
map + scale_colour_gradient(low='white', high='grey20')
map + scale_colour_grey()

You need to use scale_fill_* and not scale_color_*. For the polygon geometry the fill color of the polygons is coupled to the fill aesthetic, not to the color aesthetic. In general, the function used to change the details of a particular scale is scale_aesthetic_name_type_of_scale, e.g. scale_fill_gradient.

This code works for me.
library(ggplot2)
states <- map_data("state")
var <- data.frame(table(states$region))
states$variable <- var$Freq[match(states$region,var$Var1)]
map <- ggplot(states, aes(x=long, y=lat,fill=variable,group=group)) + geom_polygon()
map + scale_fill_gradient(low='white', high='grey20')
An easy way to handle problems with discrete variables is to create a "fake" continuous palette using the color palette function. See the below example.
Define color palette, here I used the hex codes for black and white but you can use any colors
gs.pal <- colorRampPalette(c("#FFFFFF","#000000"),bias=.1,space="rgb")
Now create some fake data
x <- rnorm(100)
dat <- data.frame(cbind(x))
dat$fac <- as.factor(sort(rep(1:5,20)))
dat$y <- x * as.numeric(dat$fac)
Next plot it with the ggplot function scale_*type _manual in this case since its color
in you'd use scale_colour_manual but above you'd use scale_fill_manual
ggplot(dat,aes(x=x,y=y,colour=fac))+geom_point()+scale_colour_manual(values=gs.pal(5))

Related

Ggplot and sf for overlaying two layers of polygons (.shp)

I have two polygon '.shp' files. I need one to appear on the map by filling in one variable and the other to appear only on borders, overlapping the first.
I have already used 'ggplot2' and 'sf'.
I plotted a map ('map1'), which is layered with polygons, using 'ggplot' and 'geom_sf'.
I use a variable ('var1') contained in 'map1' as a 'fill'.
Now, I need to add (overlay) another layer of polygons on top ('map2'). This will have to be 'transparent fill' or 'no fill'. Only appearing the outline of the borders.
library(ggplot2); library(sf)
map1 <- st_read("m1.shp") #reading polygon layer map 1
map2 <- st_read("m2.shp")#reading polygon layer map 2
g <- ggplot(map1, aes(fill = var1)) +
geom_sf()
How can i add 'map2' for overlay this map?
The idea would be:
g <- ggplot(map1, aes(fill = var1)) +
geom_sf() +
ggplot(map2, aes()) +
geom_sf()
#Error: Don't know how to add ggplot(map2, aes()) to a plot
Every geom_SOMETHING() function has a data argument where you can configure the data you are using. This argument plays the same role as the data argument in the ggplot() function. When you specify data in ggplot, all the other geom_SOMETHING() function inherit the argument. The same happens with the arguments in aes()
So the first recommendation is remove the data = map1 and aes arguments from ggplot and add it to the geom_sf function.
g <- ggplot() + geom_sf(map1, aes(fill = var1)) + geom_sf(map2)

ggplot geom_histogram color by factor not working properly

In trying to color my stacked histogram according to a factor column; all the bars have a "green" roof? I want the bar-top to be the same color as the bar itself. The figure below shows clearly what is wrong. All the bars have a "green" horizontal line at the top?
Here is a dummy data set :
BodyLength <- rnorm(100, mean = 50, sd = 3)
vector <- c("80","10","5","5")
colors <- c("black","blue","red","green")
color <- rep(colors,vector)
data <- data.frame(BodyLength,color)
And the program I used to generate the plot below :
plot <- ggplot(data = data, aes(x=data$BodyLength, color = factor(data$color), fill=I("transparent")))
plot <- plot + geom_histogram()
plot <- plot + scale_colour_manual(values = c("Black","blue","red","green"))
Also, since the data column itself contains color names, any way I don't have to specify them again in scale_color_manual? Can ggplot identify them from the data itself? But I would really like help with the first problem right now...Thanks.
Here is a quick way to get your colors to scale_colour_manual without writing out a vector:
data <- data.frame(BodyLength,color)
data$color<- factor(data$color)
and then later,
scale_colour_manual(values = levels(data$color))
Now, with respect to your first problem, I don't know exactly why your bars have green roofs. However, you may want to look at some different options for the position argument in geom_histogram, such as
plot + geom_histogram(position="identity")
..or position="dodge". The identity option is closer to what you want but since green is the last line drawn, it overwrites previous the colors.
I like density plots better for these problems myself.
ggplot(data=data, aes(x=BodyLength, color=color)) + geom_density()
ggplot(data=data, aes(x=BodyLength, fill=color)) + geom_density(alpha=.3)

R geom_line not plotting as expected

I am using the following code to plot a stacked area graph and I get the expected plot.
P <- ggplot(DATA2, aes(x=bucket,y=volume, group=model, fill=model,label=volume)) + #ggplot initial parameters
geom_ribbon(position='fill', aes(ymin=0, ymax=1))
but then when I add lines which are reading the same data source I get misaligned results towards the right side of the graph
P + geom_line(position='fill', aes(group=model, ymax=1))
does anyone know why this may be? Both plots are reading the same data source so I can't figure out what the problem is.
Actually, if all you wanted to do was draw an outline around the areas, then you could do the same using the colour aesthetic.
ggplot(DATA2, aes(x=bucket,y=volume, group=model, fill=model,label=volume)) +
geom_ribbon(position='fill', aes(ymin=0, ymax=1), colour = "black")
I have an answer, I hope it works for you, it looks good but very different from your original graph:
library(ggplot2)
DATA2 <- read.csv("C:/Users/corcoranbarriosd/Downloads/porsche model volumes.csv", header = TRUE, stringsAsFactors = FALSE)
In my experience you want to have X as a numeric variable and you have it as a string, if that is not the case I can Change that, but this will transform your bucket into a numeric vector:
bucket.list <- strsplit(unlist(DATA2$bucket), "[^0-9]+")
x=numeric()
for (i in 1:length(bucket.list)) {
x[i] <- bucket.list[[i]][2]
}
DATA2$bucket <- as.numeric(x)
P <- ggplot(DATA2, aes(x=bucket,y=volume, group=model, fill=model,label=volume)) +
geom_ribbon(aes(ymin=0, ymax=volume))+ geom_line(aes(group=model, ymax=volume))
It gives me the area and the line tracking each other, hope that's what you needed
If you switch to using geom_path in place of geom_line, it all seems to work as expected. I don't think the ordering of geom_line is behaving the same as geom_ribbon (and suspect that geom_line -- like geom_area -- assumes a zero base y value)
ggplot(DATA2, aes(x=bucket, y=volume, ymin=0, ymax=1,
group=model, fill=model, label=volume)) +
geom_ribbon(position='fill') +
geom_path(position='fill')
Should give you

Heat Color Densities in R

I am trying to build a type of color density plot similar to the one here:
https://stats.stackexchange.com/questions/26676/generating-visually-appealing-density-heat-maps-in-r
But with different types of data that goes into it. My real data has a bunch of rows but for example I have code that is put into a data frame that is X, Y, Score and I want to have a color density plot using these static X, Y buckets. Is that possible?
X=seq(0,10,by=1)
Y=seq(50,60,by=1)
total=expand.grid(X,Y)
nrow(total)
total$score=runif(nrow(total), min=0, max=100)
range(total$score)
head(total)
my_palette <- colorRampPalette(c("blue", "yellow", "red"))(n = 100)
col_breaks = c(seq(0,100,length=100))
col=data.frame(as.character(my_palette),col_breaks)
col$num=row.names(col)
head(col)
col$col_breaks=round(col$col_breaks,0)
names(col)[1]="hex"
total$round=round(total$score)
total$color=as.character(col$hex[match(total$round,col$col_breaks)])
plot(total$Var1,total$Var2,col=total$color,xlim=c(0,10),ylim=c(50,60))
I am not trying to hexbin or anything confine into boxes, figured that out using conditional rect() with colors but wondering with this type of data if there is a way for it to sort of be more of a freeflowing shape of heat similar to this:
Or does it need to be continuous data to do something like that?
If I understand your question correctly, I think you can do this in ggplot.
Basically you can use geom_raster to fill in the tiles with an interpolate option so it won't look "blocky". You can then set the gradient to what you want. So for example, based on the sample data you gave me I have set the low, mid, high colours to be blue, white and red respectively. It would simply be the following code:
library(ggplot2)
ggplot(total, aes(x=Var1, y=Var2)) +
geom_raster(aes(fill=score), interpolate=TRUE) +
scale_fill_gradient2(limits=c(0,100), low="blue", mid="white", high="red", midpoint = 50)
Output:

How to change ggplot legend labels and names with two layers?

I am plotting the longitude and latitude coordinates of two different data frames in São Paulo map using ggmap and ggplot packages and want to label manually each legend layer:
update: I edited my code below to become fully reproducible (I was using the geocode function instead of get_map).
update: I would like to do this without combining the data frames.
require(ggmap)
sp <- get_map('sao paulo', zoom=11, color='bw')
restaurants <- data.frame(lon=c(-46.73147, -46.65389, -46.67610),
lat=c(-23.57462, -23.56360, -23.53748))
suppliers <- data.frame(lon=c(-46.70819,-46.68155, -46.74376),
lat=c(-23.53382, -23.53942, -23.56630))
ggmap(sp)+geom_point(data=restaurants, aes(x=lon, y=lat),color='blue',size=4)+geom_point(data=suppliers, aes(x=lon, y=lat), color='red', size=4)
I have looked to several questions and tried different ways without success. Does anyone know how can I insert legend and label the blue points as restaurants and the red points as suppliers?
Now that your code is reproducible (thanks!):
dat <- rbind(restaurants,suppliers)
dat$grp <- rep(c('Restaurants','Suppliers'),each = 3)
ggmap(sp) +
geom_point(data=dat, aes(x=lon, y=lat,colour = grp),size = 4) +
scale_colour_manual(values = c('red','blue'))

Resources