tm_scale_continuous displaying with interval legend with linestrings
I'm converting v3 code to v4 and can't seem to get the new tm_scale_continuous to work with linestrings in that the continuous legend color scale reverts to intervals. Example below:
# generate 20 linestrings with numeric groups:
library(sf)
set.seed(42)
lon_min <- -180
lon_max <- 180
lat_min <- -90
lat_max <- 90
create_random_line <- function() {
lon_start <- runif(1, lon_min, lon_max)
lat_start <- runif(1, lat_min, lat_max)
lon_end <- runif(1, lon_min, lon_max)
lat_end <- runif(1, lat_min, lat_max)
st_linestring(matrix(c(lon_start, lat_start, lon_end, lat_end), ncol = 2, byrow = TRUE))
}
lines <- lapply(1:20, function(x) create_random_line())
lines_sf <- st_sfc(lines, crs = 4326) # Use WGS84 (EPSG:4326)
values_df <- data.frame(value = 1:20)
lines_sf <- st_sf(values_df, geometry = lines_sf)
library(tmap)
tm_shape(lines_sf) +
tm_lines("group",
lwd=5,
tm_scale_continuous(values="brewer.spectral")) +
tm_place_legends_right()
When changing to points tm_scale_continuous works fine (presumably as it's fill and not col?):
tm_shape(points_sf) +
tm_dots("value",
size=2,
tm_scale_continuous(values="brewer.spectral")) +
tm_place_legends_right()
is there a way of getting a continuous colorscale legend with col?
This is by (current) design. The legend in the first map are not intervals, but a regular (pretty) sample of geometries (lines in this case) in the continuous scale. I thought that this may be useful in some applications (?) From that perspective, the second map is wrong, and should also include the same sample of bubbles (so a orange bubble with 5, yellow with 10 etc). Note that a sample is also used for other visual variables (e.g. size).
Apart from the fact that maps 1 and 2 are not consistent (which they should be), the question is what you prefer:
- A regular/pretty sample showing the geometries, so lines or symbols (legend in first map)
- A continuous color box (legend in second map)
Second question: how should a user select the non-default option? What would be a good argument name in tm_legend_x?
Note-to-self: https://github.com/r-tmap/tmap/blob/master/R/tmapGridComp_leg_portrait.R#L15
I've corrected the maps below to make the example more consistent, where the tm_dots are the endpoints of the tm_lines:
points_sf <- lines_sf |> st_cast("POINT")
tm_shape(points_sf) +
tm_dots("value",
size=0.5,
tm_scale_continuous(values="brewer.spectral"), shape=21) +
tm_shape(lines_sf) +
tm_lines("value",
tm_scale_continuous(values="brewer.spectral"),
lwd=1) +
tm_place_legends_right()
With the above example, the colours are both set as tm_scale_continuous, but the tm_lines are displayed as intervals not as a colour gradient. As an asides, I don't think the map is "wrong" because the bubbles don't reflect size: often tm_bubbles is visually distracting where a fixed size and simple color gradient would suffice.
As a possible answer: why not allow tm_lines to function the same as tm_dots in terms of allowing both tm_scale_continuous and tm_scale_intervals (rather than defaulting continuous to intervals)?
Expanded example on above with tm_dots, same map, different color settings:
a <- tm_shape(points_sf) +
tm_dots("value",
size=1,
tm_scale_continuous(values="brewer.spectral"), shape=21) +
tm_labels("value",
size=0.8) +
tm_place_legends_right()
b <- tm_shape(points_sf) +
tm_dots("value",
size=1,
tm_scale_intervals(values="brewer.spectral"), shape=21) +
tm_labels("value",
size=0.8) +
tm_place_legends_right()
tmap_arrange(a,b, ncol=1)
As a clearer "real world" tmap example (hopefully!) that lead me to the question: a tm_scale_continuous legend would be more useful than an interval legend here as the linestring is a continuous (non-linear) gradient!
I have a similar comment regarding tm_scale_continuous but in my case with tm_symbols().
I'm looking the have the continuous color scale legend but so far I haven't been able to create it:
tm_basemap("Esri.WorldImagery", alpha = 0.5) +
tm_shape(SD_allsps) +
tm_symbols(
size = "radius_m", size.legend = tm_legend(show = F),
col = "fcompleteness_2021", col_alpha = 0.9,
col.scale = tm_scale_continuous(values = viridis::mako(100)),
col.legend = tm_legend(title = "Mean Completeness 2021",
position = tm_pos_in("left", "bottom"),
bg.color = "white",
text.size = 0.5, title.size = 0.6,
show = T),
fill = "fcompleteness_2021", fill_alpha = 0.1,
fill.scale = tm_scale(values = "white"), fill.legend = tm_legend(show = F))
Now by default, all continuous color scales (so both fill and col) come with a gradient legend.
Please check @marine-ecologist and @GuiAlDuS and let us know if you have further questions