pythonplotlymapboxplotly-expressplotly.graph-objects

How to use Plotly Mapbox to plot lines between a given set of markers?


I have a pandas dataframe as follows:

'links', declaring coordinates for a source and coordinates for a sink

For each row (link), I would like to plot a line between the two nodes that it declares. For example, the markers Douglas and Aberdeen Lochnagar should be plotted and connected with a line.

However, when I attempt to use go.Scattermapbox, it plots all the required lines between any two nodes BUT also many lines that are not declared in the 'links' dataframe. I believe this is because Plotly Mapbox also adds continuous lines, so if I want a line between link1 and link2 AND link3 and link4, it will also plot a line between link2 and link3 since they are adjacent in the dataframe.

I have tried using a for loop and adding a trace for each link, however the lines do not show up on the map, I want one trace of all links AND there are too many links to do this.

This is the trace I am using at the moment, which outputs all the correct links but with the addition of all the wrong ones:

trace4 = go.Scattermapbox(lat=links[['source_lat', 'sink_lat']].values.flatten(), mode='lines', lon=links[['source_lon', 'sink_lon']].values.flatten())


Solution

  • To draw a line on the map, specify the start and end points in the list. Since you already have the start and end points as columns in your data frame, you specify them.

    import plotly.graph_objects as go
    
    fig = go.Figure()
    
    for _,row in df.iterrows():
        fig.add_trace(go.Scattermapbox(mode='lines',
                                       lon=[row['source_lon'], row['sink_lon']],
                                       lat=[row['source_lat'], row['sink_lat']],
                                       line_color='green',
                                       name=row['source_name']
                                      ))
    fig.update_layout(
        height=600,
        mapbox=dict(
            style='open-street-map',
            zoom=4,
            center=dict(lon=df['source_lon'].mean(), lat=df['source_lat'].mean())
        )
    )
    fig.show()
    

    enter image description here