Gridded data on interactive map

I am looking for some guidance on this issue.

I often work with xarray data formats, which describe wind speed over a geographic area.

I think plotly is a great tool for visualization, but it lacks the feature of showing an image or gridded dataset on a map with a background tile.

For instance, one of the code examples in Heatmaps in Python
shows air temperature, which is similar to what I need, but I cannot display it on a map and keep the tooltip functionality.

Is there a better way to achieve this goal?

I have tried some alternatives in the past, such as Holoviews, geoviews, etc., but they lose the tooltip when converted to a dash app. (And I really like dash apps).

So I wonder if anyone has a better solution for this problem.

I have also used a tile server before, but that seems too complicated for small pieces of analysis.

To plotly developers: It would be awesome if you could add a px.imshow_mapbox function. That would solve my problem!

Not a square grid but have you tried hexbin_mapbox?

Do you know what, I have not. You would think the amount of time I have been working with this I would have tried this.

Will try this out and report back

OK , so had a bit of a play and thought i would come back in case there is something i am missing .

The problem with HexBin is that it is generally used to take a count or average of across an area. But as the wind speeds are related to a given area , ideally i want tp plot them all, with a bin centred at each point .

The current HexBin implementation doesn’t work for this . see example below and plot you get

am i missing something here?

import numpy as np
import plotly.figure_factory as ff
import plotly.express as px
import plotly.io as pio
pio.renderers.default='notebook'
import xarray as xr


data = xr.open_dataset(file_path)

# convert to dataframe
df = data.to_dataframe().reset_index()


#remove rows with NaN values in the wind_speed column
df = df.dropna(subset=['wind_speed'])


fig = ff.create_hexbin_mapbox(
    data_frame=df, lat="lat", lon="lon",
    nx_hexagon=100, opacity=0.9, labels={"color": "Wind Speed"},
    color="wind_speed", agg_func=np.mean, color_continuous_scale="Viridis",
    show_original_data=True, original_data_marker=dict(size=4, opacity=0.6, color="white"),
)
fig.update_layout(mapbox_style="open-street-map")
fig.update_layout(margin=dict(b=0, t=0, l=0, r=0))
fig.show()

That’s right, you won’t be able to get a grid cell per data point. If you decrease the number of hexagons slightly you’ll get a good tiling of the map, with some tiles being the average wind speed from a few data points.

From the figure you showed above it looks like the wind speed data is already interpolated rather than actual measurements so I don’t think it would make a big difference.

If you really wanted each individual point the best you can do for now is a scatter map box with large markers.