Key Takeaways: Interactive Visualization — plotly, Dashboard Thinking
This is your reference card for Chapter 17 — the chapter where your charts gained hover tooltips, zoom, animation, and geographic intelligence. Keep this nearby when you need to share explorable data with stakeholders.
The Core Idea
Static charts tell a story. Interactive charts let the audience explore. Use static (matplotlib, seaborn) when you control the narrative. Use interactive (plotly) when the audience needs to investigate, filter, and discover.
plotly.express Quick Reference
Common Chart Types
| Chart |
Function |
Key Parameters |
| Scatter |
px.scatter() |
x, y, color, size, hover_name |
| Line |
px.line() |
x, y, color, markers=True |
| Bar |
px.bar() |
x, y, color, text_auto |
| Histogram |
px.histogram() |
x, nbins, color, barmode |
| Box |
px.box() |
x, y, color, hover_data |
| Violin |
px.violin() |
x, y, color, box=True, points |
| Choropleth |
px.choropleth() |
locations, color, hover_name, projection |
| Animated scatter |
px.scatter() |
+ animation_frame, animation_group |
| Animated choropleth |
px.choropleth() |
+ animation_frame |
Encoding Variables (parallels to seaborn)
| plotly Parameter |
seaborn Equivalent |
Encodes |
color |
hue |
Color |
size |
size |
Marker area |
symbol |
style |
Marker shape |
facet_col |
col |
Horizontal panels |
facet_row |
row |
Vertical panels |
animation_frame |
(not available) |
Time animation |
| Parameter |
Purpose |
Example |
hover_name |
Bold title in tooltip |
hover_name="country" |
hover_data |
Additional fields |
hover_data=["region", "year"] |
hover_data (dict) |
Fields with formatting |
hover_data={"gdp": ":,.0f"} |
hover_data (hide) |
Exclude a field |
hover_data={"lat": False} |
Choropleth Maps
Minimum Requirements
px.choropleth(df,
locations="iso_alpha", # ISO codes
color="value_column", # What to show
hover_name="country") # Tooltip title
Important Options
| Parameter |
Purpose |
Example |
projection |
Map projection |
"natural earth", "orthographic" |
scope |
Zoom to continent |
"africa", "europe", "asia" |
color_continuous_scale |
Colormap |
"YlGnBu", "RdYlGn" |
range_color |
Fix color range |
[40, 100] |
Animation
Key Parameters
px.scatter(df, x="x", y="y",
animation_frame="year", # Time column
animation_group="country", # Entity ID
range_x=[0, 80000], # Fix axes!
range_y=[30, 100]) # Fix axes!
Rules
- Always fix axis ranges — prevents disorienting rescaling.
- Always set
animation_group — enables smooth entity tracking.
- Keep frame count reasonable — 10-30 frames, not 100.
- Fix
range_color for choropleth animations — ensures consistent color meaning.
Dash Dashboard Architecture
Structure
Layout (what the user sees)
- html.H1("Title")
- dcc.Dropdown(id="my-dropdown", options=[...])
- dcc.Slider(id="my-slider", min=..., max=...)
- dcc.Graph(id="my-chart")
Callback (what happens when user interacts)
@app.callback(
Output("my-chart", "figure"), # What to update
Input("my-dropdown", "value") # What triggers update
)
def update(selected_value):
filtered = df[df["col"] == selected_value]
return px.scatter(filtered, ...)
Common Components
| Component |
Purpose |
html.H1(), html.P() |
Headings, text |
dcc.Dropdown() |
Select from list |
dcc.Slider() |
Select numeric value |
dcc.Checklist() |
Multiple selections |
dcc.Graph() |
Display plotly chart |
Dashboard Design Principles
- Start with a question the user needs to answer
- Limit to 3-5 interactive controls
- Show the big picture first, details below
- All charts should respond to the same controls
- Provide sensible defaults — the dashboard should be informative before any interaction
Export Options
| Method |
Output |
Size |
Offline? |
fig.write_html("f.html", include_plotlyjs=True) |
Self-contained HTML |
~3-5 MB |
Yes |
fig.write_html("f.html", include_plotlyjs="cdn") |
CDN-dependent HTML |
~10-50 KB |
No |
fig.write_image("f.png", scale=2) |
Static PNG |
Varies |
Yes |
fig.write_image("f.pdf") |
Static PDF |
Varies |
Yes |
fig.write_image("f.svg") |
Scalable vector |
Varies |
Yes |
Note: Static image export requires the kaleido package.
Templates (Themes)
| Template |
Best For |
"plotly" |
Default, general use |
"plotly_white" |
Clean, modern dashboards |
"plotly_dark" |
Presentations on dark backgrounds |
"ggplot2" |
R users, academic style |
"seaborn" |
Consistency with seaborn charts |
"simple_white" |
Minimal, publication-ready |
Set globally: import plotly.io as pio; pio.templates.default = "plotly_white"
| Situation |
Best Tool |
| Printed report or paper |
matplotlib or seaborn |
| Statistical distribution analysis |
seaborn |
| Exploratory notebook work (statistics) |
seaborn |
| Share with non-technical stakeholders |
plotly (HTML export) |
| Geographic data on a map |
plotly (choropleth) |
| Temporal animation |
plotly (animation_frame) |
| Recurring dashboard for a team |
Dash |
| Maximum custom control |
matplotlib or plotly.graph_objects |
Terms to Remember
| Term |
Definition |
| plotly |
Python library for interactive web-based visualization |
| plotly.express |
High-level API for common interactive chart types |
| interactive chart |
Visualization that responds to user actions (hover, click, zoom) |
| hover tooltip |
Pop-up information displayed when the cursor is over a data point |
| zoom |
Interaction that magnifies a selected area of the chart |
| pan |
Interaction that shifts the visible area without changing zoom level |
| choropleth map |
Map where geographic regions are colored according to data values |
| animation |
Sequential display of chart states, controlled by play button and slider |
| dropdown |
UI control that lets the user select one option from a list |
| slider |
UI control that lets the user select a value along a numeric range |
| Dash |
Python framework for building interactive web dashboards with plotly |
| dashboard |
Web page combining multiple charts and controls for data exploration |
| callback |
Function that Dash runs when a user interacts with a control |
| HTML export |
Saving a plotly chart as a standalone HTML file for browser viewing |
What You Should Be Able to Do Now
- [ ] Create interactive charts with plotly.express: scatter, line, bar, histogram, box, violin
- [ ] Add informative tooltips with
hover_name and hover_data
- [ ] Encode additional variables with
color, size, symbol, facet_col, facet_row
- [ ] Build choropleth maps with country-level or state-level data
- [ ] Create animations with
animation_frame and fixed axis ranges
- [ ] Customize layouts with
update_layout(), templates, and titles
- [ ] Export to HTML with both self-contained and CDN modes
- [ ] Export static images for reports (PNG, PDF, SVG)
- [ ] Build a basic Dash app with a dropdown, graph, and callback
- [ ] Choose the right tool (matplotlib, seaborn, or plotly) based on audience and output format
If you checked every box, you are ready for Chapter 18, where you step back from code and think about design — what makes a visualization honest, accessible, and effective.