Data Science

Data Visualization

Interactive Visualization with Plotly

Every chart so far (Chapters 2-3) has been static — a fixed image. Plotly produces interactive charts: hover for exact values, zoom into a region, toggle series

JrCodex·6 min read

Jr Codex Data Science Notes

Level: Intermediate Prerequisites: Chapter 3 Time to complete: ~20 minutes


Table of Contents

  1. Static vs Interactive Visualization
  2. Plotly Express — the Quick Interface
  3. Interactive Scatter & Line Plots
  4. Interactive Bar Charts & Histograms
  5. Adding Hover Details
  6. Exporting Interactive Charts
  7. When to Use Plotly vs Matplotlib/Seaborn
  8. Summary & Next Steps

1. Static vs Interactive Visualization

Every chart so far (Chapters 2-3) has been static — a fixed image. Plotly produces interactive charts: hover for exact values, zoom into a region, toggle series on/off by clicking the legend — all without writing any extra code beyond the initial chart.

Static (matplotlib/seaborn)          Interactive (Plotly)
─────────────────────────────       ─────────────────────────────
  Fixed image (PNG, PDF)               Renders in a browser/notebook
  Great for reports, print              Great for exploration, dashboards
  Viewer sees exactly what               Viewer can hover, zoom, filter,
  you rendered                             explore beyond the initial view
─────────────────────────────       ─────────────────────────────

2. Plotly Express — the Quick Interface

plotly.express mirrors seaborn's DataFrame-first API closely — if Chapter 3 felt comfortable, this will too.

import plotly.express as px
import pandas as pd
 
df = pd.DataFrame({
    "month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
    "revenue": [45000, 52000, 48000, 61000, 58000, 67000],
})
 
fig = px.line(df, x="month", y="revenue", title="Monthly Revenue", markers=True)
fig.show()      # opens an interactive chart — hover over any point to see exact values

In a Jupyter notebook, fig.show() renders the interactive chart inline, exactly like matplotlib — the difference only becomes apparent once you actually interact with it (hover, zoom, click the legend).


3. Interactive Scatter & Line Plots

import plotly.express as px
import pandas as pd
import numpy as np
 
np.random.seed(0)
df = pd.DataFrame({
    "age": np.random.randint(20, 65, 300),
    "income": np.random.normal(60000, 20000, 300),
    "region": np.random.choice(["North", "South", "East", "West"], 300),
})
df["income"] = df["income"] + df["age"] * 300
 
fig = px.scatter(
    df, x="age", y="income", color="region",
    title="Age vs Income by Region",
    trendline="ols",           # adds a fitted regression line PER region, automatically
)
fig.show()
What the Viewer Can Do With This Chart
─────────────────────────────────────────
  - Hover over any point → see its exact age, income, region
  - Click a region in the legend → hide/show just that group
  - Click-and-drag → zoom into a specific area
  - Double-click → reset the zoom
─────────────────────────────────────────

Every one of these interactions requires zero extra code — they come built into every Plotly Express chart by default, which is exactly why Plotly is worth reaching for once an audience needs to explore data themselves rather than just view a fixed image.


4. Interactive Bar Charts & Histograms

import plotly.express as px
import pandas as pd
 
df = pd.DataFrame({
    "region": ["North", "South", "East", "West"],
    "total_spend": [125000, 98000, 87000, 143000],
})
 
fig = px.bar(df, x="region", y="total_spend", color="region",
             title="Total Spend by Region", text="total_spend")
fig.update_traces(texttemplate="$%{text:,.0f}", textposition="outside")
fig.show()
import plotly.express as px
import numpy as np
 
data = np.random.gamma(2, 100, 1000)
 
fig = px.histogram(data, nbins=40, title="Spend Distribution")
fig.show()      # hover over any bar to see its exact count and range

5. Adding Hover Details

The default hover already shows x/y values — hover_data extends it with any additional columns worth surfacing:

import plotly.express as px
import pandas as pd
import numpy as np
 
df = pd.DataFrame({
    "customer_id": range(1, 21),
    "age": np.random.randint(20, 65, 20),
    "income": np.random.normal(60000, 15000, 20),
    "region": np.random.choice(["North", "South"], 20),
    "num_orders": np.random.randint(1, 50, 20),
})
 
fig = px.scatter(
    df, x="age", y="income", color="region",
    hover_data=["customer_id", "num_orders"],      # extra fields shown ONLY on hover
    title="Age vs Income (hover for customer details)",
)
fig.show()

This is a direct upgrade over a static chart's usual workaround — annotating individual outlier points manually (tedious, and only feasible for a handful of points) — for interactive charts, every point's full context is available on demand.


6. Exporting Interactive Charts

import plotly.express as px
import pandas as pd
 
df = pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
fig = px.line(df, x="x", y="y")
 
# Export as a SELF-CONTAINED interactive HTML file — no Python needed to view it
fig.write_html("interactive_chart.html")
 
# Export as a static image (requires the `kaleido` package: pip install kaleido)
fig.write_image("static_chart.png")
Sharing an Interactive Chart
─────────────────────────────────────────
  .write_html()  → the recipient just opens it in ANY browser, no Python
                    installed, and gets the FULL interactive experience
  .write_image()  → for embedding in a static report/document, same as
                      matplotlib's savefig() (Chapter 2)
─────────────────────────────────────────

This is one of Plotly's biggest practical advantages: a single .html file is a fully interactive, shareable artifact that works for anyone with a web browser — no Jupyter, no Python environment required on the recipient's end.


7. When to Use Plotly vs Matplotlib/Seaborn

Decision Guide
─────────────────────────────────────────
  Static report, academic paper, printed document
      → matplotlib/seaborn (Chapters 2-3) — precise, print-ready, PDF/SVG export

  Sharing exploration results with someone who'll want
  to dig into specifics themselves (zoom, hover, filter)
      → Plotly — export as standalone HTML

  Building a full interactive dashboard/app
      → Plotly, feeding into Streamlit (Chapter 5)
─────────────────────────────────────────
Matplotlib/SeabornPlotly
OutputStatic imageInteractive (browser-rendered)
Best forReports, papers, printExploration, sharing, dashboards
Fine visual controlVery high (Chapter 2)Good, but less granular
Learning curveModerateLow, if already comfortable with seaborn's API

8. Summary & Next Steps

Key Takeaways

  • Plotly produces interactive charts — hover, zoom, and legend-toggling come built in, with an API (plotly.express) that closely mirrors seaborn's DataFrame-first style.
  • hover_data surfaces additional context per point on demand, solving the static-chart problem of only being able to annotate a handful of points manually.
  • fig.write_html() exports a fully self-contained, interactive file viewable in any browser — no Python needed by the recipient.
  • Choose matplotlib/seaborn for static reports and print; choose Plotly for shared, exploratory, or dashboard-bound visualizations.

Concept Check

  1. What can a viewer do with a Plotly chart that they can't do with a static matplotlib chart?
  2. Why is hover_data useful even after x and y are already shown by default?
  3. When would you export a chart as .html instead of .png?

Next Chapter

Chapter 5: Building a Dashboard with Streamlit


Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index