Search code examples
plotlymapboxsubplot

Make subplots with Plotly hexbin


I'm trying to include multiple hexbin map box plots into a single figure. Is there a way to achieve this Plotly subplots. I've got three distinct values below that I want to plot in three separate figures but am returning an error saying hexbin map box is not supported.

If a hexbin map box is not supported, can a 2d histogram replace it?

import pandas as pd
import plotly.express as px
import plotly.graph_objs as go
import plotly.figure_factory as ff
from plotly.subplots import make_subplots

data = pd.DataFrame({
       'Cat': ['t','y','y','y','f','f','t','f','y','y','t','y','f','f'],
       'LAT': [5,6,4,5,4,7,8,9,5,6,18,17,15,16],
       'LON': [10,11,9,11,10,8,8,5,8,7,18,16,16,17],
       })

df_t = data[data['Cat'] == 't']
df_t = data[data['Cat'] == 'y']
df_t = data[data['Cat'] == 'f']

fig = make_subplots(
    rows = 3, 
    cols = 1, 
    subplot_titles = ('t', 'y', 'f'),
    specs = [[{"type": "hexbinmapbox"}, {"type": "hexbinmapbox"}, {"type": "hexbinmapbox"}]],
    vertical_spacing = 0.05,
    horizontal_spacing = 0.05
    )

Error:

ValueError: Unsupported subplot type: 'hexbinmapbox'

Solution

  • This is my first time subplotting a hexbin graph, but I have reused figure_factory data to create a subplot. The graph type of the subplot is choroplethmapbox, not hexbinmapbox. for trace in fig.data:print(trace.type) You can see this by checking the graph type. Normally fig.data[0] is the data structure of the graph, so I just add it with a matrix specification and I am done, but in this case it did not work. The error returns a mapbox specification error. I looked into this and found a tip in the Plotly community. It is to update the mapbox settings every time. Adding it created the intended subplot.

    import pandas as pd
    import plotly.express as px
    import plotly.graph_objs as go
    import plotly.figure_factory as ff
    from plotly.subplots import make_subplots
    
    data = pd.DataFrame({
           'Cat': ['t','y','y','y','f','f','t','f','y','y','t','y','f','f'],
           'LAT': [5,6,4,5,4,7,8,9,5,6,18,17,15,16],
           'LON': [10,11,9,11,10,8,8,5,8,7,18,16,16,17],
           })
    
    df_t = data[data['Cat'] == 't']
    df_y = data[data['Cat'] == 'y']
    df_f = data[data['Cat'] == 'f']
    
    fig = make_subplots(
        rows = 3, 
        cols = 1, 
        subplot_titles = ('t', 'y', 'f'),
        specs = [[{"type": "choroplethmapbox"}], [{"type": "choroplethmapbox"}], [{"type": "choroplethmapbox"}]],
        vertical_spacing = 0.05,
        horizontal_spacing = 0.05
        )
    
    fig2 = ff.create_hexbin_mapbox(data_frame=df_t,
                                   lat="LAT", lon="LON",
                                   nx_hexagon=10,
                                   opacity=0.5,
                                   labels={"color": "Point Count"},
                                   min_count=1,
                                   mapbox_style='carto-positron',
                                   zoom=10)
    fig3 = ff.create_hexbin_mapbox(data_frame=df_y,
                                   lat="LAT", lon="LON",
                                   nx_hexagon=10,
                                   opacity=0.5,
                                   labels={"color": "Point Count"},
                                   min_count=1,
                                   mapbox_style='carto-positron',
                                   zoom=10)
    fig4 = ff.create_hexbin_mapbox(data_frame=df_f,
                                   lat="LAT", lon="LON",
                                   nx_hexagon=10,
                                   opacity=0.5,
                                   labels={"color": "Point Count"},
                                   min_count=1,
                                   mapbox_style='carto-positron',
                                   zoom=10)
    
    fig.add_trace(fig2.data[0], row=1,col=1)
    fig.update_mapboxes(zoom=3, center=dict(lat=data['LAT'].mean(),lon=data['LON'].mean()), style='carto-positron')
    fig.add_trace(fig3.data[0], row=2,col=1)
    fig.update_mapboxes(zoom=3, center=dict(lat=data['LAT'].mean(),lon=data['LON'].mean()), style='carto-positron')
    fig.add_trace(fig4.data[0], row=3,col=1)
    fig.update_mapboxes(zoom=3, center=dict(lat=data['LAT'].mean(),lon=data['LON'].mean()), style='carto-positron')
    
    fig.update_layout(autosize=True, height=600, margin=dict(t=20,b=0,l=0,r=0))
    fig.show()
    

    enter image description here