Visualization Basics
8 examples to get you started with Visualization - 6 basic and 2 intermediate.
Prerequisites
- Python 3.14.0 with matplotlib, seaborn, and pandas 2.2+.
- Quick setup:
uv pip install matplotlib seaborn pandas plotly
Basic Examples
1. Line Chart for Trends
Show change over ordered time or categories.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
revenue = [120, 135, 128, 150]
plt.plot(months, revenue, marker="o")
plt.ylabel("Revenue ($k)")
plt.title("Monthly Revenue")
plt.tight_layout()
plt.savefig("trend.png", dpi=150)
plt.close()- Line charts need ordered x-axis - not arbitrary categories.
- Markers help sparse series; dense series can omit them.
- Always call
plt.close()in scripts to free memory.
Related: matplotlib - figures and axes
2. Bar Chart for Comparisons
Compare discrete categories side by side.
import matplotlib.pyplot as plt
regions = ["East", "West", "Central"]
totals = [420, 380, 290]
plt.bar(regions, totals, color=["#2c7bb6", "#abd9e9", "#fdae61"])
plt.ylabel("Total revenue")
plt.tight_layout()- Bar length encodes magnitude - start y-axis at zero for honesty.
- Sort bars by value when order is not intrinsic.
- Limit categories (~15) or switch to horizontal bars.
Related: seaborn - statistical bar plots
3. Histogram for Distributions
Reveal spread and skew of a numeric variable.
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(42)
values = rng.normal(100, 15, size=500)
plt.hist(values, bins=20, edgecolor="white")
plt.xlabel("Score")
plt.ylabel("Count")- Bin count affects story - try 15-30 bins for hundreds of points.
- Density=True compares distributions with different sample sizes.
- Pair with box/violin plots when comparing groups.
Related: seaborn -
histplotand KDE
4. Scatter for Relationships
Explore correlation between two numeric variables.
import matplotlib.pyplot as plt
ad_spend = [10, 20, 15, 30, 25]
revenue = [120, 180, 150, 240, 210]
plt.scatter(ad_spend, revenue, alpha=0.7)
plt.xlabel("Ad spend ($k)")
plt.ylabel("Revenue ($k)")- Alpha transparency helps overplotting clusters.
- Add regression line via seaborn
regplotwhen trend is the message. - Label outliers when they drive decisions.
Related: seaborn -
scatterplotwith hues
5. seaborn Statistical Defaults
Get readable themes and color palettes quickly.
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({"region": ["East", "West"] * 5, "revenue": range(10)})
sns.set_theme(style="whitegrid")
sns.barplot(data=df, x="region", y="revenue", estimator=sum, errorbar=None)
plt.tight_layout()data=API avoids manual axis juggling.estimatoranderrorbarcontrol aggregation semantics.- Reset theme after if mixing raw matplotlib styles.
Related: seaborn - EDA workflows
6. Save Publication-Quality Output
Control dpi, bbox, and vector formats.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot([1, 2, 3], [1, 4, 9])
fig.savefig("chart.pdf", bbox_inches="tight") # vector for print
fig.savefig("chart.png", dpi=300, bbox_inches="tight")
plt.close(fig)- PDF/SVG scale cleanly in reports; PNG needs dpi (150 screen, 300 print).
bbox_inches="tight"trims excess margins.- Explicit
fig, axpattern scales to subplots.
Related: matplotlib - figure lifecycle
Intermediate Examples
7. Interactive Plotly Hover
Explore dense points with tooltips in the browser.
import plotly.express as px
import pandas as pd
df = pd.DataFrame({"x": range(20), "y": [i**1.5 for i in range(20)], "cat": ["A", "B"] * 10})
fig = px.scatter(df, x="x", y="y", color="cat", hover_data=["x", "y"])
fig.write_html("scatter.html")- HTML exports embed in dashboards without a server.
- Plotly shines for cross-filter linked views.
- For static reports, prefer matplotlib/seaborn.
Related: Plotly - interactive charts
8. Declarative Altair Chart
Compose grammar-of-graphics specs that stay readable.
import altair as alt
import pandas as pd
df = pd.DataFrame({"month": ["Jan", "Feb", "Mar"], "revenue": [120, 135, 128]})
chart = alt.Chart(df).mark_line(point=True).encode(x="month", y="revenue")
chart.save("revenue.json") # Vega-Lite spec- Altair enforces tidy data - one row per observation.
- JSON specs version-control well in git.
- Large data needs aggregation before Altair.
Related: Altair - declarative encoding
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.