'Is there a way to control which vertices connect in a plotly.express.line_geo map?
I'm trying to make a connection map that has the option to use an animation_frame to show different months/years. Plotly.express has this option, but the plotly.express.line_geo maps seem to just attach the vertices of the network at random. I was looking at these examples from https://plotly.com/python/lines-on-maps/.
import plotly.express as px
df = px.data.gapminder().query("year == 2007")
fig = px.line_geo(df, locations="iso_alpha",
color="continent", # "continent" is one of the columns of gapminder
projection="orthographic")
fig.show()
Plotly.graph_objects allows you to map actual connections between vertices, but doesn't seem to have an animation option.
import plotly.graph_objects as go
import pandas as pd
df_airports = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_february_us_airport_traffic.csv')
df_airports.head()
df_flight_paths = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_february_aa_flight_paths.csv')
df_flight_paths.head()
fig = go.Figure()
flight_paths = []
for i in range(len(df_flight_paths)):
fig.add_trace(
go.Scattergeo(
locationmode = 'USA-states',
lon = [df_flight_paths['start_lon'][i], df_flight_paths['end_lon'][i]],
lat = [df_flight_paths['start_lat'][i], df_flight_paths['end_lat'][i]],
mode = 'lines',
line = dict(width = 1,color = 'red'),
opacity = float(df_flight_paths['cnt'][i]) / float(df_flight_paths['cnt'].max()),
)
)
fig.show()
Does anyone know of a way that i could make a map like the flight path map, but allow an animation option to look at the flight maps for different months/years?
Solution 1:[1]
- you can animate any trace type using frames
- taking sample flight path data used in question, have split it into groups based on first letter of start airport
- there is no need to create a trace per flight, instead create pairs of start end locations in arrays separated by None
- with this it is simple to create a frame with a trace for each group
- then just create the figure from the frames, plus a default trace
- add play button and slider
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
df_flight_paths = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/2011_february_aa_flight_paths.csv"
)
frames = []
# lets split data based on first letter of start airport
# create a frame for each grouping
bins = 6
for color, df in df_flight_paths.groupby(
pd.qcut(
df_flight_paths["airport1"].str[0].apply(ord),
q=bins,
labels=px.colors.qualitative.Plotly[:bins],
)
):
name = f'{df["airport1"].str[0].min()}-{df["airport1"].str[0].max()}'
frames.append(
go.Frame(
name=name,
data=go.Scattergeo(
lon=df.assign(nan=None)[["start_lon", "end_lon", "nan"]].values.ravel(),
lat=df.assign(nan=None)[["start_lat", "end_lat", "nan"]].values.ravel(),
mode="lines",
line=dict(width=1, color=color),
),
)
)
# now create figure and add play button and slider
go.Figure(
data=frames[0].data,
frames=frames,
layout={
"updatemenus": [
{
"type": "buttons",
"buttons": [{"label": "Play", "method": "animate", "args": [None]}],
}
],
"sliders": [
{
"active": 0,
"steps": [
{
"label": f.name,
"method": "animate",
"args": [[f.name]],
}
for f in frames
],
}
],
},
).update_geos(
scope="north america",
)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rob Raymond |

