Reputation: 203
tm dots seems to have issues with a column that identifies the desired shape of a given observation
from the shapes enum:
0 = Open Square
1 = Open Circle
22 = Filled Square
21 = Open Circle
When I set the shape argument to 'shapeCol' where shapeCol is a column of 0 / 1 (open shapes), it returns a filled but otherwise correct shape
When I manually set the shape to 0 it returns the correct open shape but I need this shape to vary by observation
library(sf)
library(tmap)
library(dplyr)
newDf <- data.frame(location=letters[1:30],
lat=32+runif(30,0.01,0.03),
lon=-97+runif(30,.01,.03)) %>%
mutate(rowID=1:n(),
reservoir=case_when(rowID<=15 ~ 'Codell',
TRUE ~'Niobrara'))
newSf <- st_as_sf(newDf,coords=c('lon','lat'),crs=4326)
shapes <- c('Niobrara'='circle',
'Codell'='square')
shapeVals <- c('circle'=21,'square'=22,'triangleup'=24,'diamond'=23,'triangleDown'=25)
borderVals <- c('circle'=0,'square'=1,'triangleup'=2,'diamond'=5,'triangleDown'=6)
newSf.fin <- newSf %>% mutate(shapeType = shapes[reservoir],
shapeCol = as.factor(shapeVals[shapeType]),
borderCol = as.factor(borderVals[shapeType]))
newSf.fin %>% select(borderCol) # 0 and 1 / Open Shapes
#returns filled shapes despite shape column only referencing open values
tm_shape(newSf.fin) + tm_dots(shape='borderCol',size=2)
#returns open shapes by manually setting shape value
tm_shape(newSf.fin) + tm_dots(shape=0,size=2)
I know that this could be alleviated by map/looping but color scales would be more problematic and difficult. Is there a way to achieve correct open shapes based off a column value?
Upvotes: 1
Views: 1798
Reputation: 6441
I'm no tmap
expert, but this seems to be a misunderstanding.
In the documentation it says about the shape
argument:
shape(s) of the symbol. Either direct shape specification(s) or a data variable name(s) that is mapped to the symbols specified by the shapes argument. See details for the shape specification.
And about the shapes
argument it says:
palette of symbol shapes. Only applicable if shape is a (vector of) categorical variable(s). See details for the shape specification. By default, the filled symbols 21 to 25 are taken.
So when you do shape = 0
you're doing a direct shape specification. That's why it works. When you use a variable name you need to map it's categories to the shapes
-argument. You're not doing that so it takes 21 and 22, which are its default shapes and these are filled square and filled circle.
That's how it worked for me:
tm_shape(newSf.fin) + tm_dots(shape= 'borderCol',size=2, shapes = c(1, 0))
Upvotes: 2