mapview icon indicating copy to clipboard operation
mapview copied to clipboard

Plot a histogram with the values of the clicked pixel in a mapview with raster stack layer

Open agronomofiorentini opened this issue 3 years ago • 6 comments

Dear contributors, I would like to ask you if it is possible to create a histogram with the values of the pixel clicked in a map defined with mapview containing a stack layer.

With this function the shiny user can appreciate the temporal evolution of the value in a given pixel and be able to make considerations on the possible causes of such variation.

agronomofiorentini avatar Mar 29 '22 11:03 agronomofiorentini

Do you have an example where we could see such a histogram?

tim-salabim avatar Mar 29 '22 11:03 tim-salabim

Yes of course

I will attach the jpeg of the plot that i would like to generate on click on the mapview with the stack layer.

newplot (1)

If you need i could also share the single raster layers tiff format.

agronomofiorentini avatar Mar 29 '22 12:03 agronomofiorentini

If it's in a shin context, this should be possible via leaflet's shiny functions already shouldn't it?

tim-salabim avatar Mar 29 '22 14:03 tim-salabim

I will try to follow your suggestion and try to create a reproducible example and bring it back here.

I hope to succeed, in case then you could help me out.

Thanks Tim, I appreciate it

agronomofiorentini avatar Mar 29 '22 15:03 agronomofiorentini

Maybe for reprex purposes there a raster stack NDVI data set in library(cubeview)... Should be enough for a reprex.

tim-salabim avatar Mar 29 '22 15:03 tim-salabim

Hi Tim this is the reproducible code that i have produced till now

library(shiny)
library(cubeview)
library(raster)
library(leaflet)
library(mapview)
library(waiter)
library(data.table)

ui <- fluidPage(

  use_waiter(),

  titlePanel("Old Faithful Geyser Data"),

  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)
    ),

    mainPanel(
      plotOutput("distPlot"),
      leafletOutput("map"),
      plotOutput("plot_map")
    )
  )
)

server <- function(input, output) {

  output$distPlot <- renderPlot({
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })

  kili_data <- system.file("extdata", "kiliNDVI.tif", package = "cubeview")
  kiliNDVI <- stack(kili_data)

  output$map<-renderLeaflet({
    mapview(kiliNDVI)@map
  })

  data_extracted<-reactive({
    req(input$map_click)

    waiter_show(html = tagList(spin_dots(),
                               br(),
                               br(),
                               "Extraction of data..."))

    on.exit(waiter_hide())

    x<-input$map_click$lng
    y<-input$map_click$lat

    position_point<-data.frame(x, y)
    coordinates(position_point)<-~x+y
    crs(position_point)<-"+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
    position_point<-spTransform(position_point, CRSobj = crs(kiliNDVI))

    data_extracted<-raster::extract(kiliNDVI,
                                    position_point,
                                    df=TRUE)

    data_extracted<-data.table::melt(data_extracted)

    data_extracted<-data_extracted[-1,]

    return(data_extracted)
  })

  output$plot_map<-renderPlot({
    req(data_extracted())
    barplot(data_extracted()$value,
            names.arg=data_extracted()$variable)
  })

}

shinyApp(ui = ui, server = server)

It is working good. I couldn't use the leaflet Object events because didn't accept the tiles as input for those action (https://rstudio.github.io/leaflet/shiny.html). So i have extracted the position of the click in the map and then i have extracted the value by using the extract R function of the raster package.

What do you think?

agronomofiorentini avatar Mar 29 '22 20:03 agronomofiorentini