tylermorganwall / rayshader

R Package for 2D and 3D mapping and data visualization
https://www.rayshader.com/
2.06k stars 214 forks source link

add_overlay: Error in `hillshade[, , 1] * (1 - overlay[, , 4])` : non-conformable arrays #46

Closed lindsayplatt closed 5 years ago

lindsayplatt commented 5 years ago

I've searched for a fix for this, but I just can't seem to find one. The only related conversation was on Twitter and you said you fixed the issue in a commit around Dec 17, 2018 (which I thought might be this one).

I have been trying to debug, but my overlay image passes all the checks and is failing near the end (https://github.com/tylermorganwall/rayshader/blob/master/R/add_overlay.R#L122) and I can't figure out why. Below is my reproducible example.

I am using version 0.10.2

library(rayshader)

elev_file <- "sf-elevation.tif"
download.file("https://github.com/lindsayplatt/makerspace-sandbox/raw/master/rayshader/input/sf-elevation.tif",
              destfile = elev_file, mode = "wb")
elev_img <- raster::raster(elev_file)
elev_matrix <- matrix(
  raster::extract(elev_img, raster::extent(elev_img), buffer = 1000), 
  nrow = nrow(elev_img), ncol = ncol(elev_img)
)

img_file <- "overlay.png"
download.file("https://github.com/lindsayplatt/makerspace-sandbox/raw/master/rayshader/input/overlay.png",
              destfile = img_file, mode = "wb")
overlay_img <- png::readPNG(img_file)

# Without overlay works
elev_matrix %>%
  sphere_shade(texture = "imhof1") %>%
  plot_3d(elev_matrix)

# With overlay fails
elev_matrix %>%
  sphere_shade(texture = "imhof1") %>%
  add_overlay(overlay_img, alphalayer = 0.5) %>%
  plot_3d(elev_matrix)
tylermorganwall commented 5 years ago

The overlay needs to be the same dimensions as the hillshade (in this case, 400x400). I inserted some extra code to show how you can resize the overlay using base R:


elev_file <- "sf-elevation.tif"
download.file("https://github.com/lindsayplatt/makerspace-sandbox/raw/master/rayshader/input/sf-elevation.tif",
              destfile = elev_file, mode = "wb")
elev_img <- raster::raster(elev_file)
elev_matrix <- matrix(
  raster::extract(elev_img, raster::extent(elev_img), buffer = 1000), 
  nrow = nrow(elev_img), ncol = ncol(elev_img)
)

img_file <- "overlay.png"
download.file("https://github.com/lindsayplatt/makerspace-sandbox/raw/master/rayshader/input/overlay.png",
              destfile = img_file, mode = "wb")
overlay_img <- png::readPNG(img_file)

resized_overlay_file = paste0(tempfile(),".png")
grDevices::png(filename = resized_overlay_file, width = dim(elev_matrix)[1], height = dim(elev_matrix)[2])
par(mar = c(0,0,0,0))
plot(as.raster(overlay_img))
dev.off()
overlay_img = png::readPNG(resized_overlay_file)

# Without overlay works
elev_matrix %>%
  sphere_shade(texture = "imhof1") %>%
  plot_3d(elev_matrix)

# With overlay fails
elev_matrix %>%
  sphere_shade(texture = "imhof1") %>%
  add_overlay(overlay_img, alphalayer = 0.5) %>%
  plot_3d(elev_matrix)

overlay

I will include this code built-in to the next version to automatically resize the overlay and display a warning so you won't have to run this code yourself. But until then, this should work.

lindsayplatt commented 5 years ago

Excellent! I thought I had pulled down an image of that exact size, but I suppose not. Automatically resizing with a warning would be awesome. Thanks! ✔️

tylermorganwall commented 5 years ago

Fixed in 1954bc85c151f536b25058b6152bb09bdc67c54b

nitschkematthew commented 5 years ago

Hi @tylermorganwall @lindsayplatt . I think I am encountering the same issue with overlays. I have installed the latest version of rayshader from github (0.12.0). When the hillshade matrix dimensions are evaluated against the overlay dimensions it seems that the hillshade has been transposed. I have tried the overlay in both orientations and have double checked the dimensions. I am hoping you can spot where I went wrong!

library(rayshader)
library(rgdal)
library(raster)
library(png)
library(EBImage)
# Load in satellite image and get the CRS
sentinel <- stack("Sentinel-2 L2A from 2019-07-31.tiff")
sentinelcrs <- sentinel@crs@projargs

# Load in bathymetry data as raster, and convert to same CRS as satellite image
lizbath <- raster("li_20m.txt")
proj4string(lizbath) <- CRS("+init=epsg:28355")
lizbath_p <- projectRaster(lizbath, crs = sentinelcrs)

# Now that CRS are matching, crop satellite image to match extent of bathymetry
sentinel_c <- crop(sentinel, lizbath_p)

# Read in bathymetry table as matrix and transpose for rayshader
elmat <- t(as.matrix(read.table("li_20m.txt", header = FALSE, sep = " ", skip = 6)))
elmat[elmat == -9999] <- -40.24729 # Replace missing values
elmat[is.na(elmat)] <- -40.24729 # Replace NAs

# Save the cropped satellite image with dimensions matching the baythmetry matrix
plotRGB(sentinel_c)
dev.print(png, "overlay.png", width = dim(elmat)[1], height = dim(elmat)[2], units = "px")

# Read in the overlay and transpose it so that dimensions match elmat
overlay <- readPNG("overlay.png")
overlay_trans <- EBImage::transpose(overlay)

# Also do a visual check that the orientations and dimensions are matching
EBImage::display(overlay_trans)
EBImage::display(elmat)

# This works
elmat %>%
  sphere_shade(texture = "imhof4") %>%
    plot_3d(elmat,
            zscale = 10,
            water = TRUE,
            waterdepth = 0,
            wateralpha = 0.5,
            watercolor = "blue")

# Adding overlay fails with error
elmat %>%
  sphere_shade(texture = "imhof4") %>%
    add_overlay(overlay_trans, alphacolor = .9) %>%
    plot_3d(elmat,
            zscale = 10,
            water = TRUE,
            waterdepth = 0,
            wateralpha = 0.5,
            watercolor = "blue")

# Error Message: Overlay doesn't match dimension of hillshade--resizing to matchError in alphalayer1[j, i] : subscript out of bounds

Now lets do some testing to make sure that the dimensions are correct

# Create a hillshade to test dimensions
sphere_test <- elmat %>%
  sphere_shade(texture = "imhof4")

# Test for equal dimensions
dim(elmat)[1:2] == dim(overlay_trans)[1:2] # Evaluates to TRUE TRUE
dim(elmat)[1:2] == dim(sphere_test)[1:2] # Evaluates to FALSE FALSE
dim(overlay_trans)[1:2] == dim(sphere_test)[1:2] # Evaluates to FALSE FALSE
beedawg1985 commented 3 years ago

I'm experiencing this issue ... see below.

sessionInfo()

R version 4.1.1 (2021-08-10)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 10.16

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_3.3.5    remotes_2.4.0    rayshader_0.26.2

loaded via a namespace (and not attached):
 [1] rgl_0.107.14       Rcpp_1.0.7         prettyunits_1.1.1  png_0.1-7          class_7.3-19       ps_1.6.0          
 [7] rprojroot_2.0.2    digest_0.6.28      foreach_1.5.1      utf8_1.2.2         R6_2.5.1           e1071_1.7-9       
[13] pillar_1.6.3       rlang_0.4.11       progress_1.2.2     curl_4.3.2         rstudioapi_0.13    callr_3.7.0       
[19] labeling_0.4.2     desc_1.4.0         devtools_2.4.2     htmlwidgets_1.5.4  munsell_0.5.0      proxy_0.4-26      
[25] compiler_4.1.1     xfun_0.26          pkgconfig_2.0.3    pkgbuild_1.2.0     htmltools_0.5.2    tidyselect_1.1.1  
[31] tibble_3.1.5       codetools_0.2-18   fansi_0.5.0        crayon_1.4.1       dplyr_1.0.7        withr_2.4.2       
[37] sf_1.0-2           grid_4.1.1         jsonlite_1.7.2     gtable_0.3.0       lifecycle_1.0.1    DBI_1.1.1         
[43] magrittr_2.0.1     units_0.7-2        scales_1.1.1       KernSmooth_2.23-20 cli_3.0.1          cachem_1.0.6      
[49] farver_2.1.0       fs_1.5.0           doParallel_1.0.16  testthat_3.1.0     ellipsis_0.3.2     generics_0.1.0    
[55] vctrs_0.3.8        iterators_1.0.13   tools_4.1.1        glue_1.4.2         rayimage_0.6.2     purrr_0.3.4       
[61] hms_1.1.1          processx_3.5.2     pkgload_1.2.2      parallel_4.1.1     fastmap_1.1.0      colorspace_2.0-2  
[67] sessioninfo_1.1.1  classInt_0.4-3     memoise_2.0.0      knitr_1.36         usethis_2.0.1  
library(ggplot2)
devtools::install_github("tylermorganwall/rayshader")
library(rayshader)

mtplot_density = ggplot(mtcars) + 
  stat_density_2d(aes(x=mpg,y=disp, fill=..density..), geom = "raster", contour = FALSE) +
  scale_x_continuous(expand=c(0,0)) +
  scale_y_continuous(expand=c(0,0)) +
  scale_fill_gradient(low="pink", high="red")
mtplot_density
plot_gg(mtplot_density, width = 4,zoom = 0.60, theta = -45, phi = 30, 
        windowsize = c(1400,866))
render_snapshot(clear = TRUE)

Error in hillshade[, , 1] * scales::rescale(shadowmap, c(max_darken, 1)) :                                                
  non-conformable arrays
Debobrata-Sadhukhan commented 2 years ago

Warning message: In make_shadow(heightmap, shadowdepth, shadowwidth, background, : magick package required for smooth shadow--using basic shadow instead.

Sys.sleep(0.2) render_snapshot() render_snapshot()

And we can add a raytraced layer from that sun direction as well:

elmat %>%

  • sphere_shade(texture = "desert") %>%
  • add_water(detect_water(elmat), color = "desert") %>%
  • add_shadow(ray_shade(elmat), 0.5) %>%
  • plot_map() Error in hillshade[, , 1] * scales::rescale(shadowmap, c(max_darken, 1)) : non-conformable arrays

Getting this error please help me how can I fix this?