Plotting heatmap with lat/lon specified

Hi,

I’m trying to plot a raster image onto a lat/lon coordinate plane. The ggplot output looks like this:

However, when I attempt to turn this plot into a plotly object, I get the error message “Warning message:
’heatmap’ objects don’t have these attributes: ‘mode’”. My plotting code is as follows:

r_spdf <- as(d, "SpatialPixelsDataFrame") # turn raster to SPDF
r_df <- as.data.frame(r_spdf)

names(r_df)[1] <- "Thermal Habitat" #Change column name for legend title

p <- ggplot() +  
  geom_polygon(data=boundary, aes(x=long, y=lat), fill="#9AC5E3") +           #Ocean
  geom_sf(data = ne_countries, fill = "white",color = "white", size = 0.25) +     #USA
  geom_sf(data = ne_states, fill = "white",color = "white", size = 0.05) +          #States
  geom_tile(data=r_df, aes(x=x, y=y, fill=`Thermal Habitat`), alpha=0.8) +     #Raster layer
  scale_fill_gradient2(low = "blue",mid = "white",high = "red",midpoint = 0.5) +#Color
  coord_sf(crs = crs, xlim = xlims, ylim = ylims) +                       #Coordinate limits
  
  theme_map() +
  theme(legend.text = element_blank(),
  plot.background=element_blank(),
  panel.border=element_blank())
    
    plt <- ggplotly(p) %>%
        layout(
          title = "Black Sea Bass Thermal Habitat",
          titlefont = list(size = 15),
          margin = list(b = 50, t = 50),
          autosize = F,
          width = 500,
          legend = list(x = 0.1, y = 0.9,
          bgcolor = "#E2E2E2",
          bordercolor = "#FFFFFF",
          borderwidth = 2)
        )

After doing some reading, I found that I need to turn the raster layer into a matrix before incorporating with plotly, but the problem is that I lose also lat/lon data when I do so. How can I keep lat/lon information to turn the above figure into a plotly compatible heatmap?

Hi again,

I was able to get this working properly. Thanks to Sandy Muspratt’s post for providing some more guidance. The key was to avoid specifying any layers as sf objects, or using any functions involving *_sf in the plotting code. This seems to only be necessary when using plotly with geom_tile.

r_spdf <- as(d, "SpatialPixelsDataFrame")
r_df <- as.data.frame(r_spdf)


m_df <- r_df %>%
  reshape2::melt(id = c("y","x")) %>%
  dplyr::rename(lat = y, long = x) %>%
  dplyr::select(-variable)

 #For world map
center <- 0 # positive values only

# Get world map
worldmap <- map_data ("world")

#center and filter to region
worldmap$long.recenter <- ifelse(worldmap$long < center - 180 , worldmap$long + 360, worldmap$long)
map <- worldmap %>% filter (long > -78, long < -50, lat > 30, lat <60)
  
#base + geom_tile
p <- ggplot(data = map, aes(x = long, y = lat)) +
  geom_polygon(aes(group = group), fill="#f9f9f9", colour = "grey65")+
  coord_fixed(xlim = xlims, ylim = ylims) +  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks = element_blank(), 
        panel.border = element_rect(colour = "black")) +
  geom_tile(data = m_df, aes(y = lat, x = long, fill = value)) +
  scale_fill_gradient2(low = "blue",mid = "white",high = "red",midpoint = 0.5)

#plotly
plt <- ggplotly(p) %>%
    layout(
      title = "Black Sea Bass Thermal Habitat",
      titlefont = list(size = 15),
      margin = list(b = 50, t = 50),
      autosize = F,
      width = 500,
      legend = list(x = 0.1, y = 0.9,
      bgcolor = "#E2E2E2",
      bordercolor = "#FFFFFF",
      borderwidth = 2)
    )
plt

Here’s a png of the plotly output.

newplot

three reasons why you should buy plotly pro: support open source, get great support, host your plots and dashboards online