I'm creating a cloropleth map of the U.S where each county is colored by the proportion of the 2012 votes for Obama. I'd like to vary the opacity of county overlays by the population (similar to what was done here). I've tried adding alpha = populationVariable to my geom_map aes, but without luck.
Here is my current code. Can anyone point me in the right direction?
gg <- ggplot()
gg <- gg + geom_map(data=mapC, map=mapC, aes(x=long, y=lat, map_id=id, group=group, fill=mapC$proportionObama))
gg = gg+ scale_fill_gradient2(limits= c(0,100), name="Proportion of Votes for Obama", low="#E5000A", high="#0012BF",mid="#720964", midpoint=50)
gg = gg + theme_map() +coord_equal()
gg <- gg + geom_path(data = mapS, aes(long,lat, group=group), colour="gray50", size=.25)
gg = gg + theme(legend.position="right")
gg
I think that alpha needs to be a variable that's mapped to be between 0 and 1. The ggplot documentation always shows a fractional value.
Hue Scale - http://docs.ggplot2.org/0.9.3.1/scale_hue.html
Color Fill Alpha - http://docs.ggplot2.org/current/aes_colour_fill_alpha.html
You don't have reproducible code, so here was a quick test that seemed to work.
library(data.table)
library(ggplot2)
tmp = data.table(
'x'=c(1,2,3),
'y'=c(1,2,3),
'z'=c(.1,.5,.8)
)
p = ggplot()
p = p + geom_point( data=tmp , aes(x=x,y=y,alpha=z))
print(p)
Related
This question already has answers here:
Force R to stop plotting abbreviated axis labels (scientific notation) - e.g. 1e+00
(9 answers)
Closed 8 months ago.
I am making a choropleth with ggplot and I am trying to fit the labels for my legend in the frame but R keeps putting the labeled values in scientific notation. Does anyone know of a way to address this? I have the following code which works fine when the values of my labels are smaller, but I need to include the range.
ta<- quantile(look13$capcpi,c(0, 0.2, 0.4, 0.6, 0.8, 1.0) )
t<- c('$35,141-$37,916', '$37,916-$40,236','$40,236-$43,364','$43,364-$45,280', '$45,280-$59,688')
look13$capcpi_q<- cut(look13$capcpi,ta, lables= t, include.lowest = TRUE)
lookmap<- merge(st,look13, by.x='id', by.y= 'area')
realpi<- ggplot(lookmap, aes(x=long, y=lat, group=group, fill= capcpi_q))+
geom_path() + geom_polygon(color='black')+
scale_fill_manual(values= pal)+ theme_clean()
Generally, you can use the scales package and a label parameter to scale_color_continuous (or discrete):
library(ggplot2)
library(scales)
library(ggthemes)
# make up some data
dat <- data.frame(state=tolower(rownames(USArrests)),
rate=USArrests$Murder*10000000,
stringsAsFactors=FALSE)
us <- map_data("state")
gg <- ggplot()
gg <- gg + geom_map(data=us, map=us,
aes(x=long, y=lat, map_id=region),
color="#7f7f7f", size=0.15, fill="white")
gg <- gg + geom_map(data=dat, map=us,
aes(fill=rate, map_id=state))
gg <- gg + scale_fill_continuous(label=comma)
gg <- gg + coord_map("albers", 39, 42)
gg <- gg + theme_map()
gg
I'm trying to plot a continuous variable on space. I saw this example that gets the same result that I need:
library("MASS")
library("ggplot2")
library(reshape2)
DB<-melt(volcano)
ggplot(DB, aes(x=Var1, y=Var2, fill=value)) +geom_tile()
So I did with my data:
library(repmis)
url<-"https://www.dropbox.com/s/4m5qk32wjgrjq40/dato.RDATA"
source_data(url)
library(ggplot2)
ggplot(dato,aes(y=variable,x=y,fill=value))+geom_tile()
That's wonderful. But my "x" and "y" are kilometers distance (east and north) from a point in space. I transformed these in latitude and longitude. But now my plot doesn't work!
ggplot(dato,aes(y=lat,x=long,fill=value))+geom_tile()
I don't understand why. Anyway plotting my data like points the result is very similar:
ggplot(dato,aes(y=lat,x=long,fill=value))+geom_point()
ggplot(dato,aes(y=variable,x=y,fill=value))+geom_point()
You can cheat a bit and use geom_point with a square shape:
#devtools::install_github("sjmgarnier/viridis")
library(viridis)
library(ggplot2)
library(ggthemes)
library(scales)
library(grid)
gg <- ggplot(dato)
gg <- gg + geom_point(aes(x=long, y=lat, color=value), shape=15, size=5)
gg <- gg + coord_equal()
gg <- gg + scale_color_viridis(na.value="#FFFFFF00")
gg <- gg + theme_map()
gg <- gg + theme(legend.position="right")
gg
I did not project the lat/long pairs and just used coord_equal. You should use a proper projection for the region being mapped.
And, now you have me curious as to what those hot spots are around Milan :-)
gmap <- get_map(location=c(9.051062, 45.38804, 9.277473, 45.53438),
source="stamen", maptype="toner", crop=TRUE)
gg <- ggmap(gmap)
gg <- gg + geom_point(data=dato, aes(x=long, y=lat, color=value), shape=15, size=5, alpha=0.25)
gg <- gg + coord_map()
gg <- gg + scale_color_viridis(na.value="#FFFFFF00")
gg <- gg + theme_map()
gg <- gg + theme(legend.position="right")
gg
So, I have a dataset that has data for not only CONUS but also the island areas and Alaska. Now, I want to plot only the data for CONUS. I know I can subset it easily. But is there any easier way to that? Maybe an option in ggplot I don't know?
Here is the code:
ggplot() +
geom_polygon( data=usamap, aes(x=long, y=lat,group=group),colour="black", fill="white" )+
geom_point(data=df,aes(x=Longitude,y=Latitude))+
scale_colour_gradientn(name = "DL",colours = myPalette(10))+
xlab('Longitude')+
ylab('Latitude')+
coord_map(projection = "mercator")+
theme_bw()+
theme(legend.position = c(.93,.20),panel.grid.major = element_line(colour = "#808080"))+
ggsave("test.png",width=10, height=8,dpi=300)
Here is the dataset:
https://www.dropbox.com/s/k1z5uquhtc2b9nd/exported.csv?dl=0
You can do it and also use a decent projection at the same time:
library(ggplot2)
library(readr)
library(dplyr)
us <- map_data("state")
us <- fortify(us, region="region")
# for theme_map
devtools::source_gist("33baa3a79c5cfef0f6df")
# read your data and filter out points not in CONUS
read_csv("exported.csv") %>%
filter(Longitude>=-124.848974 & Longitude<=-66.885444,
Latitude>=24.396308 & Latitude<=49.384358) -> data
gg <- ggplot()
gg <- gg + geom_map(data=us, map=us,
aes(x=long, y=lat, map_id=region, group=group),
fill="#ffffff", color="#7f7f7f", size=0.25)
gg <- gg + geom_point(data=data,
aes(x=Longitude, y=Latitude),
color="#cb181d", size=1, alpha=1/10)
gg <- gg + coord_map("albers", lat0=39, lat1=45)
gg <- gg + theme_map()
gg
You have no aesthetic color mapping I can see, so your color scaling will have no impact. I used an alpha for overlapping/close points instead.
Looking at your reposted question, I think by far the best way is a simple subset. From this link, you can see the box around the continental USA is:
(-124.848974, 24.396308) - (-66.885444, 49.384358)
if you do a simple subset:
usamap<-usamap[usamap$Longitude > -124.848 &
usamap$Longitude < -66.886 &
usamap$Latitude > 24.3964 &
usamap$Latitude < 49.3844, ]
You will get your required points.
Since you said you'd be interested in a ggplot2 solution, you might consider modifying the arguments in coord_map(). For example:
coord_map(project = "globular",
xlim = c(-125, -66),
ylim = c(24, 50))
Of course, the "mercator" argument works, too!
Edited as a response to #hrbrmstr's great answer:
I'm mapping 2 groups of countries and would like a legend to go with it. Since I'm using my own data, it's hard to provide a MRE. In my previous code I was using geom_polygon to plot the shapes (read from a shapefile) because fortify throws away the additional data the associated dataframe:
ggplot() + aes(long, lat, group = group) + theme_bw() +
scale_x_continuous(limits = c(-15, 35)) +
scale_y_continuous(limits = c(25, 75)) +
scale_fill_manual("Affected?", labels = c("Yes", "No"),
values = c("gray10", "gray80")) +
geom_polygon(data = affected.countries, fill = "gray10", color = "black") +
geom_polygon(data = unaffected.countries, fill = "gray80", color = "black")
The result:
Now I've tried taking a page from #hrbrmstr's playbook. Because fortify throws away my other columns, I made 2 subsets of my original data, which is of class SpatialPolygonsDataFrame. I fortify them and given them a dummy variable that shows what I need and then try to plot them using the boolean column to control the fill:
affected.countries <- fortify(affected.countries)
affected.countries$affected <- T
unaffected.countries <- fortify(unaffected.countries)
unaffected.countries$affected <- F
# all.countries now contains column affected
all.countries <- rbind(affected.countries, unaffected.countries)
gg <- ggplot() + coord_map(xlim = c(-13, 35), ylim = c(32, 71)) + theme_bw()
# Base map
gg <- gg + geom_map(data = all.countries, map = all.countries,
aes(x = long, y = lat, map_id = id),
fill = NA, color="gray10")
# Base map looks OK
gg
# Add filled data
gg <- gg + geom_map(data = all.countries, map = all.countries,
aes(fill = affected, map_id = id),
fill="gray10")
# For some reason, everything is filled!
gg <- gg + scale_fill_manual("Affected?", labels = c("No", "Yes"),
values = c("gray80", "gray10"))
# And the legend isn't shown
gg
For these results:
I thought the problem was that my fill argument wasn't in aes, but here it is. Sadly, I don't see a way of using a second dataframe as in #hrbrmstr's answer, since I don't have the appropriate columns in my data, but I thought the boolean column would solve it. And although I could do it by hacking the code from the answer, I'd prefer my own country boundaries.
Notably, if I include the fill argument outside the aes but inside the geom_polygon call, the fill works correctly, but the legend isn't shown. If I specify the color in aes, a seemingly random color is shown.
What principle am I missing? Thanks again!
Here's a more complete example, esp since there was no projection used nor data provided in the original question:
library(ggplot2)
europe <- map_data('world',
region=c('Switzerland', 'Liechtenstein', 'Luxembourg',
'UK', 'Belgium', 'Norway', 'Germany', 'Ireland',
'Austria', 'France', 'Netherlands', 'Sweden',
'Denmark','Italy' ))
condition <- data.frame(region=c("Ireland", "France", "Netherlands",
"Sweden", "Finland", "UK", "Germany"),
affected=c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE),
stringsAsFactors=FALSE)
gg <- ggplot()
# base map
gg <- gg + geom_map(data=europe, map=europe,
aes(x=long, y=lat, map_id=region),
color="#7f7f7f", fill="white", size=0.25)
# fills according to affected
gg <- gg + geom_map(data=condition, map=europe,
aes(fill=affected, map_id=region),
color="#7f7f7f", size=0.01)
# a minimally decent projection tho one of the conical ones is prbly better
gg <- gg + coord_map(xlim=c(-13, 35), ylim=c(32, 71))
# fills for the aes mapping
gg <- gg + scale_fill_manual("Affected?", labels = c("No", "Yes"),
values = c("gray80", "gray10"))
# no need for axis labels since it's a map
gg <- gg + labs(x=NULL, y=NULL)
gg <- gg + theme_bw()
gg
As Gregor pointed out, this is a sub-optimal projection (but since there was no projection in the original post I didn't want to just toss one in besides the default Mercator). In case you wonder why a few of us obsess over projections on SO, take this one report as an example (a whole document from one of many workshops on just European projections).
There are a couple other choices. First, Lambert Conic Conformal, which you can use by changing the coord_map to:
gg <- gg + coord_map("lambert", lat0=32, lat1=71, xlim=c(-13, 35), ylim=c(32, 71))
Even though the linked-to document doesn't suggest using it, Gilbert is also (IMO) a decent one to use:
gg <- gg + coord_map("gilbert", xlim=c(-13, 35), ylim=c(32, 71))
The PDF also suggests Azimuth Equal Area is an preferred option:
gg <- gg + coord_map("azequalarea", xlim=c(-13, 35), ylim=c(32, 71))
I am not following your entire questions with the updates involved. But perhaps it could be a simple as setting guide = TRUE in scale_fill_manual(). See Turning off some legends in a ggplot.
I'm trying to plot a US map where each state is shaded by the count that it has. I've gotten the shading to work just fine. The problem I'm running into, however, is that the polygons look very jagged (I'm assuming something happened when I tried to merge the map_data('state') with my data frame of counts per state). My data frame before merging has 49 rows (Nevada was missing data in my set), and after merging has many more rows (expected for the long/lat items for the states) but the data appears to be copied correctly for each lat/long pair, so I'm unsure why the poly's are so jagged.
Code:
ggplot() +
geom_polygon(data=try1, aes(x=long, y=lat, group = group, fill= COUNT)) +
scale_fill_continuous(low='thistle2', high='darkred', guide='colorbar') +
theme_bw() + labs(fill="State Map Try Title1", title='Title2', x='', y='') +
scale_y_continuous(breaks=c()) +
scale_x_continuous(breaks=c()) +
theme(panel.border = element_blank())
Any help would be greatly appreciated (and obviously, if there is a better way to do it, I'm open to suggestions!).
You don't need to do the merge. You can use geom_map and keep the data separate from the shapes. Here's an example using the built-in USArrests data (reformatted with dplyr):
library(ggplot2)
library(dplyr)
us <- map_data("state")
arr <- USArrests %>%
add_rownames("region") %>%
mutate(region=tolower(region))
gg <- ggplot()
gg <- gg + geom_map(data=us, map=us,
aes(x=long, y=lat, map_id=region),
fill="#ffffff", color="#ffffff", size=0.15)
gg <- gg + geom_map(data=arr, map=us,
aes(fill=Murder, map_id=region),
color="#ffffff", size=0.15)
gg <- gg + scale_fill_continuous(low='thistle2', high='darkred',
guide='colorbar')
gg <- gg + labs(x=NULL, y=NULL)
gg <- gg + coord_map("albers", lat0 = 39, lat1 = 45)
gg <- gg + theme(panel.border = element_blank())
gg <- gg + theme(panel.background = element_blank())
gg <- gg + theme(axis.ticks = element_blank())
gg <- gg + theme(axis.text = element_blank())
gg
I encountered a similar problem when using ggplot2. As an alternative to #hrbrmstr 's solution, I found reloading the ggplot2 package (as well as rgdal/`maptools') resolved the issue for me.