R - Adding dots to map in tmap

2019-08-17 21:52发布

问题:

My map-making code generates a map based on census data and plots important points as a tm_dots() layer. What I'd like to be able to do is differentiate between the types of dots (e.g. if the location is "Informal" or "Commercial").

tm_shape(bristol) + tm_fill("population", palette = "YlOrRd", 
auto.palette.mapping = TRUE, 
  title = "Bristol Population", 
  breaks = c(0,5,10,15,20,25), colorNA = "darkgrey") + tm_borders("grey25",alpha = 0.7, lwd = 0.1) +
  tm_dots("n", size=0.1,col="green", shapeNA = NA, title = "Spaces") + 
  tm_legend(text.size=1,title.size=1.2,position=c("left","top")) + 
  tm_layout(legend.outside = TRUE, legend.outside.position = "bottom", title.snap.to.legend = TRUE)

What I'm looking for is essentially:

tm_dots("n", size=0.1,col=Classification, shapeNA = NA, title = "Spaces")

Adding several tm_dots() layers isn't an option. I also can't rename the dot legend, any advice on that too is appreciated.

Thanks for your help!

Solution

For future reference, I added offices to bristol via left_join, thus adding the Classification variable to the SpatialPolygonsDataFrame. I was having issues with it displaying NA values despite the showNA = NA parameter, but colorNA = NULL worked. Final line: tm_dots(size=0.1,col="Classification", palette = "Set1", colorNA = NULL)

回答1:

So bristol is a polygon shape (SpatialPolygonDataFrame or sf), and you want to plot dots in some polygons?

Normally, you would have a variable Offices, with two levels "Informal" and "Commercial". Then it's just tm_dots(size = 0.1, col = "Offices"). If you want to place two dots in one polygons because there are Informal and Commercial offices, then you can use your own approach (and use xmod and/or ymod for one group to prevent overlap), or create a SpatialPointsDataFrame or sf object with all offices, and a variable Offices with two levels as described above.



回答2:

I figured it out, you need to have another tm_shape() for it to work. Still haven't got the title() to appear properly but one step at a time.

tm_shape(bristol) + tm_fill("population", palette = "YlOrRd", auto.palette.mapping = TRUE, 
  title = "Bristol Population", 
  breaks = c(0,5,10,15,20,25), colorNA = "darkgrey") + tm_borders("grey25",alpha = 0.7, lwd = 0.1) +
  tm_dots("Informal_Offices", size=0.1,col="green", shapeNA = NA, title = "Informal Offices") + 
  tm_shape(bristol) + tm_dots("Commercial_Offices", size=0.1,col="white",shapeNA=NA, title="Commercial Offices") + 
  tm_legend(text.size=1,title.size=1.2,position=c("left","top")) + 
  tm_layout(legend.outside = TRUE, legend.outside.position = "bottom", title.snap.to.legend = TRUE)

Result