contentintech
Learn/data science/Data Visualization
Beginner~20 min read

Data Visualization

Plotting essentials with matplotlib, seaborn, and plotly: figures and axes, chart types, subplots, styling, and choosing the right chart.

matplotlibseabornplotlycharts

The Visualization Stack

Three libraries cover almost every need. matplotlib is the low-level foundation with total control. seaborn sits on top for beautiful statistical charts in one line. plotly produces interactive charts for dashboards and notebooks.

python
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import pandas as pd, numpy as np

Figure & Axes

matplotlib has two APIs. Prefer the explicit object-oriented style: create a Figure (the canvas) and one or more Axes (the plots), then call methods on the Axes.

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

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, np.sin(x), label="sin")
ax.set_title("A Simple Line")
ax.set_xlabel("x")
ax.set_ylabel("sin(x)")
ax.legend()
fig.tight_layout()
plt.show()

OO vs pyplot

The stateful plt.plot() style is fine for quick throwaway plots, but the fig, ax style scales to complex, multi-panel figures without surprises.

Core Chart Types

Four plot types cover the majority of everyday needs.

Line

Best for trends over an ordered axis such as time.

python
fig, ax = plt.subplots()
ax.plot(x, y, color="teal", linewidth=2, linestyle="--")

Scatter

Shows the relationship between two numeric variables.

python
ax.scatter(df["height"], df["weight"],
           c=df["age"], cmap="viridis", alpha=0.7)

Bar

Compares a numeric value across categories.

python
counts = df["team"].value_counts()
ax.bar(counts.index, counts.values)
ax.barh(counts.index, counts.values)   # horizontal

Histogram

Reveals the distribution of a single numeric variable.

python
ax.hist(df["score"], bins=20, edgecolor="white")

Subplots

Arrange multiple Axes in a grid to compare views side by side. plt.subplots(rows, cols) returns the figure and an array of Axes.

python
fig, axes = plt.subplots(1, 2, figsize=(10, 4))

axes[0].plot(x, np.sin(x))
axes[0].set_title("sin")

axes[1].plot(x, np.cos(x))
axes[1].set_title("cos")

fig.suptitle("Trig Functions")
fig.tight_layout()

# 2x2 grid -> index with [row][col]
fig, axes = plt.subplots(2, 2)
axes[0][1].hist(data)

Styling

A few settings dramatically improve readability. Apply a style sheet, set limits and ticks, and always label axes.

python
plt.style.use("seaborn-v0_8-darkgrid")   # global theme

fig, ax = plt.subplots()
ax.plot(x, y, marker="o", markersize=4)
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
ax.grid(True, alpha=0.3)
ax.set_xticks([0, 5, 10])
ax.annotate("peak", xy=(1.6, 1), xytext=(3, 0.9),
            arrowprops=dict(arrowstyle="->"))

fig.savefig("chart.png", dpi=150, bbox_inches="tight")

seaborn: Statistical Plots

seaborn takes a tidy DataFrame and column names, then does the heavy lifting. It shines for distributions, relationships, and correlation matrices.

Distributions

python
sns.histplot(df, x="score", hue="team", kde=True)
sns.boxplot(df, x="team", y="score")
sns.violinplot(df, x="team", y="score")

Heatmaps

python
corr = df.select_dtypes("number").corr()
sns.heatmap(corr, annot=True, cmap="coolwarm",
            vmin=-1, vmax=1, fmt=".2f")

Pairplot

python
# scatter matrix of every numeric pair, colored by category
sns.pairplot(df, hue="team", diag_kind="kde")

seaborn returns matplotlib

seaborn draws onto matplotlib Axes, so you can still tweak the result with ax.set_title(...) and other matplotlib methods afterward.

plotly: Interactive Glimpse

plotly express creates zoomable, hoverable charts with the same tidy-DataFrame API. Perfect for exploration and web dashboards.

python
fig = px.scatter(df, x="height", y="weight",
                 color="team", size="age",
                 hover_name="name")
fig.show()

px.line(df, x="date", y="revenue", color="region")
px.bar(df, x="team", y="score")
px.histogram(df, x="score", nbins=20)

Choosing the Right Chart

Match the chart to the question you are answering, not to what looks impressive.

GoalChartFunction
Trend over timeLineax.plot
Relationship (2 numeric)Scatterax.scatter
Compare categoriesBarax.bar
DistributionHistogram / KDEsns.histplot
Spread & outliersBox / Violinsns.boxplot
Correlation matrixHeatmapsns.heatmap
Part of a wholeStacked barax.bar(bottom=)

Avoid pie charts

Humans compare lengths far better than angles. A bar chart almost always communicates proportions more clearly than a pie chart, especially with more than 3 slices.

Design Principles

Good charts share a few habits: label every axis with units, start bar-chart y-axes at zero, use color intentionally (not decoratively), and remove clutter that does not carry information.

Practice Exercises

  1. Using the object-oriented API, plot both sin(x) and cos(x) on the same Axes with a legend and title.
  2. Create a 1x2 subplot figure: a histogram of one column on the left and a scatter plot on the right.
  3. Load a dataset and draw a seaborn boxplot of a numeric column grouped by a category.
  4. Compute the correlation matrix of the numeric columns and visualize it as an annotated heatmap.
  5. Build a plotly express scatter plot with color and size encoding two extra variables, and hover labels.
  6. For a "revenue by month" question, pick the right chart type and justify your choice in one sentence.

Section navigation