plotly for interactive charts
Level 3 · Lesson 6
Hook
matplotlib makes a chart. plotly makes a chart you can hover, zoom, and filter. For exploratory analysis and embedded dashboards, the interactivity pays for itself. For static reports, stick with matplotlib.
Concept
plotly has two APIs: plotly.express for one-liner charts (great for exploration) and plotly.graph_objects for fine control (great for final charts).
import plotly.express as px
fig = px.line( df, x='week', y='passing_yards', color='player_display_name', markers=True, title='Goff weekly passing yards, 2024', labels={'passing_yards': 'Passing yards', 'week': 'Week'},)fig.update_layout( plot_bgcolor='white', showlegend=False,)fig.show() # in Jupyterfig.write_html('goff-passing.html') # embeddable in the L5 appThe four moves to make a plotly chart presentation-ready:
- Pass labels.
labels={...}controls axis titles without renaming the DataFrame. - Clean the background.
plot_bgcolor='white',showlegend=Falseif a legend isn’t earning its space. - Color intentionally.
color_discrete_sequence=['#0076B6', '#999']or pass a dict mapping categories to colors. - Write to HTML.
fig.write_html('out.html')produces a single-file chart you can embed in the L5 Next.js app.
Lions example
Lions weekly points scored, interactive:
import pandas as pdimport plotly.express as pxfrom sqlalchemy import create_engine
eng = create_engine("postgresql+psycopg://onepride:lions@localhost:5432/onepride")
df = pd.read_sql( """ SELECT week, CASE WHEN home_team = 'DET' THEN home_score ELSE away_score END AS pts, CASE WHEN home_team = 'DET' THEN away_team ELSE home_team END AS opp FROM schedules WHERE season = 2024 AND game_type = 'REG' AND (home_team = 'DET' OR away_team = 'DET') ORDER BY week """, eng,)
fig = px.bar( df, x='week', y='pts', hover_data=['opp'], title='Lions points scored by week, 2024 regular season', labels={'pts': 'Points', 'week': 'Week'}, color_discrete_sequence=['#0076B6'],)fig.update_layout(plot_bgcolor='white', xaxis=dict(tickmode='linear'))fig.write_html('lions-weekly-points-2024.html')Hover over a bar and you see the opponent. Drag-zoom in. Save as HTML and you have an embeddable chart for the L5 app.
Try it
Make a plotly line chart of Goff’s weekly passing yards in 2024 with
markers at each week, hover showing completions and attempts. Save it as
goff-2024.html.
Common mistakes
- Default plotly theme. It’s busy. Set
plot_bgcolor='white', drop the legend if there’s one series, and remove gridlines that aren’t earning a read. - Tooltips with no value. The default tooltip can be noisy or
uninformative — explicitly set
hover_data=[...]to the columns that matter. - Too many series. Same as matplotlib — five lines is the practical
ceiling. Use faceting (
facet_col=) for small multiples. - Forgetting to write HTML.
fig.show()is great in Jupyter; for the L5 app you wantfig.write_html(...).
Quick check
- When is plotly the right call vs matplotlib?
- What’s the difference between
plotly.expressandplotly.graph_objects? - How do you embed a plotly chart in the L5 Next.js app?