Skip to main content

Data Visualization with Matplotlib and Seaborn

A good chart answers one question clearly.

Choosing a chart​

QuestionChart
How is a variable distributed?Histogram, box plot, violin plot
How do two numeric variables relate?Scatter plot (plus a trend line)
How do categories compare?Bar chart
How does something change over time?Line chart
How are many variables correlated?Heatmap of the correlation matrix
Parts of a whole (few categories)Stacked bar (avoid pie with many slices)

Matplotlib basics​

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, np.sin(x), label="sin(x)")
ax.plot(x, np.cos(x), label="cos(x)", linestyle="--")
ax.set_title("Trigonometric functions")
ax.set_xlabel("x")
ax.set_ylabel("value")
ax.legend()
ax.grid(alpha=0.3)
fig.tight_layout()
fig.savefig("trig.png", dpi=150)

Seaborn for statistical plots​

import seaborn as sns
import matplotlib.pyplot as plt

tips = sns.load_dataset("tips")

sns.histplot(tips, x="total_bill", hue="time", kde=True)
plt.show()

sns.boxplot(tips, x="day", y="tip")
plt.show()

sns.scatterplot(tips, x="total_bill", y="tip", hue="smoker")
plt.show()

corr = tips.corr(numeric_only=True)
sns.heatmap(corr, annot=True, cmap="coolwarm", vmin=-1, vmax=1)
plt.show()

Design principles​

  • Label axes with units; title states the takeaway.
  • Start bar charts at zero; truncated axes exaggerate differences.
  • Use few colours; make them colour-blind safe (for example the viridis palette).
  • Remove clutter: heavy borders, 3D effects, redundant legends.
  • Annotate the important point instead of making readers search.

Common misleading charts​

ProblemBetter
Truncated y-axis on a bar chartStart at zero or use a dot plot
Dual axes with different scalesTwo separate charts
Pie chart with 10 slicesSorted bar chart
Cherry-picked time windowShow the full period