Open MilesMcBain opened 3 years ago
Simpler reprex with the long lake osm data:
library(ggplot2)
library(stars)
library(ggspatial)
library(raster)
stars_rgb <- stars::read_stars(system.file("longlake/longlake.tif", package = "ggspatial"))
ggspatial:::load_longlake_data(which = c("longlake_osm"), raster_format = "raster")
ggplot() +
layer_spatial(longlake_osm)
ggsave("raster.png", width = 12, height = 8, units = "in")
ggplot() +
layer_spatial(stars_rgb)
ggsave("stars.png", width = 12, height = 8, units = "in")
Thanks for reprexing this so nicely! I'll do a more thorough investigation in a few, but I think if you set interpolate = TRUE
for both, you should get the same result. I do some guessing to try to figure out whether or not to use interpolation, and it looks like my guessing is incorrect somewhere!
Setting interpolate = TRUE
makes a marginal improvement but so marginal that at first I thought it was having no effect.
I think it's because st_warp
uses an inferior interpolation method by default, compared with the bilinear interpolation that gets used in the raster case.
I tried to turn on bilinear interpolation in the st_warp
call in raster_grob_from_stars
however the template_raster
that is created is not compatible with the dest
argument expected by st_warp
for this case. It seems that it needs to have the data, so that dest[[1]]
can work.
Ooof. Thanks for putting the time in to diagnose this...I'll fix in the next few days!
I think this is fixed...I couldn't get stars::st_warp()
to work for this, so I went straight to sf::gdal_util("warp", ...)
. Let me know if this fixes the problem (or creates new ones...)! I need to improve my testing for stars objects...this issue reminded me that they need serious updating.
This is a vast improvement. Interestingly to my eyes raster
still somehow has the edge. See the latest stars.png
:
It looks like raster
is hand rolling it's own bilinear interpolation. The png file size it produces is slightly larger.
But I think this is good enough. Thankyou!
Maybe I'm naive, but why would you do a bilinear interpolation on an image with a categorical variable?
That's not what's happening here. This long lake data is just an example.
The real use is for map images that have text, hillshading, roads, glyphs etc. Could also have satellite images as base layer.
But the comment does make me think that the interpolate
arg may have a confusing name.
Interpolation always occurs to match the raster size to the plot size, however when interpolate = TRUE
bilinear interpolation is done instead of nereast neighbour. So maybe you're better off having an 'interpolation_method` arg? 🤔
@edzer You don't! The default for interpolate
is FALSE
except for RGB (although my detection of RGB isn't perfect). I changed this after you brought it up in a previous thread (thanks!).
I'll investigate the lower quality and add some tests for stars objects...the code isn't quite as I remember it and likely has a few other issues.
interpolate = TRUE/FALSE
is was named from the current geom_raster()
, which I think takes the name from rasterGrob()
. Really, there's two interpolations happening...one if/when the raster has to be reprojected (operates on values) and one when the colours get resampled to match the screen resolution (operates on colours). Ideally there would only be one (each screen pixel would get resampled + coloured once for each window resize), but when I tried this a few years ago I ran into some limitations. Ideally I'd like to solve those issues together...I think interpolate = TRUE
or interpolate = FALSE
does the job most of the time.
I am struggling to understand why the output I get for
{stars}
RGB rasters withlayer_spatial
looks so grainy when compared with{raster}
RGB rasters? Is there some kind of interpolation happening?An example follows. Note the difference in image quality produced by
ggsave
using the same parameters onraster
vsstars
.Code in the
as_stars_tile
function here comes from @edzer in :https://github.com/r-spatial/stars/issues/315. It depends on the dev version ofstars
.stars.png
raster.png