Bug using tmap to plot world map
Dear maintainer,
When we use tmap plot a world map in R 4.1.2, there is a mistake.
library(tmap)
library("rnaturalearth")
world <- ne_countries(scale = "medium", returnclass = "sp")
test <- tm_shape(world) +
tm_polygons(col = "scalerank")
tmap_save(test, filename = "test.jpg")
The warning message is as follows:
Warning message:
The shape world is invalid. See sf::st_is_valid

However, when I use 4.0.3, no such mistake or warning message appears.
Here is the version info and package version.
> packageVersion('tmap')
[1] ‘3.3.3’
> version
_
platform x86_64-w64-mingw32
arch x86_64
os mingw32
system x86_64, mingw32
status
major 4
minor 1.2
year 2021
month 11
day 01
svn rev 81115
language R
version.string R version 4.1.2 (2021-11-01)
nickname Bird Hippie
Thank you.
Probably this has something to do with the underlying libraries or the spatial drivers (proj, geos and gdal) which may have been updated along with R itself.
You can try to repair the object with sf::st_make_valid.
Closing this issue as it seems not to be related to {tmap}. Keep us posted if you're still seeing this issue @MichaelChaoLi-cpu, do you get it with the plot() function also?
plot() is ok. However, the tmap does not work, even run sf::st_make_valid.
library(tmap)
library("rnaturalearth")
library(sp)
world <- ne_countries(scale = "medium", returnclass = "sp")
test <- tm_shape(world) +
tm_polygons(col = "scalerank")
tmap_save(test, filename = "test.jpg")
world <- ne_countries(scale = "medium", returnclass = "sf")
world2 <- sf::st_make_valid(world)
(test2 <- tm_shape(world2) +
tm_polygons(col = "scalerank") )
tmap_save(test2, filename = "test2.jpg")
world <- ne_countries(scale = "medium", returnclass = "sp")
world@data <- world@data %>% dplyr::select('level')
plot(world)
jpeg(file="test3.jpeg", width = 297, height = 210, units = "mm", quality = 300, res = 300)
plot(world)
dev.off()
test2

test3

So I think that might be a bug.
Thanks.
Aha reopening now... Can anyone else reproduce this?
Try disabling S2 at the beginning of your code -- sf_use_s2(FALSE).
sf_use_s2(FALSE) works. Thank you @Nowosad @Robinlovelace @mtennekes