Mastering Matplotlib: A Practical Guide to Data Visualization in Python

Matplotlib Essentials

Core Concepts

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = 2 * x + 1
y2 = x ** 2
plt.figure(num=3, figsize=(8, 5))
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--')
plt.show()

Axis Ranges and Labels

plt.xlim((-1, 2))
plt.ylim((-2, 3))
plt.xlabel('I am x')
plt.ylabel('I am y')

Handling Chinese Characters

plt.rcParams['font.sans-serif']=['SimHei']

Tick Configuration

# Hide axis ticks
plt.xticks(())
plt.yticks(())

# Rotate tick labels
plt.xticks(rotation=90)

# Custom tick values
plt.xticks(np.linspace(-1, 2, 5))
plt.yticks([-3, -1.8, -1, 1.22, 3], [r'$very poor$', r'$poor$', r'$average$', r'$good$', r'$excellent$'])

Spines and Borders

ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

Repositioning Axes

ax = plt.gca()
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))

Text and Annotations

# Add text labels at specified coordinates
for x, y in zip(X, Y1):
    plt.text(x + 0.05, y + 0.05, '%.2f' % y, ha='center', va='bottom')

# Add annotated arrows
plt.annotate('midpoint', xy=(x_mid, y_mid), xytext=(5, 30.),
             textcoords='offset points', arrowprops={'facecolor': 'black', 'shrink': 0.05})

Legends

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = 2 * x + 1
y2 = x ** 2
plt.figure()
l1, = plt.plot(x, y2, label='quadratic curve')
l2, = plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--', label='linear curve')
plt.yticks([-3, -1.8, -1, 1.22, 3], [r'$very poor$', r'$poor$', r'$average$', r'$good$', r'$excellent$'])
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.legend(handles=[l1, l2], labels=['parabola', 'line'], loc='best')
plt.show()

Horizontal and Vertical Lines

plt.axhline(0.7, color='red', ls='--')
plt.axhline(y=5, xmin=0.1, xmax=0.9)
plt.axvline(x=5, ymin=0.1, ymax=0.9)

Point Annotation

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y = 2 * x + 1
plt.figure(figsize=(8, 5))
plt.plot(x, y)
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))

x0, y0 = 1, 2 * 1 + 1
plt.plot([x0, x0], [0, y0], 'k--', linewidth=2.5)
plt.scatter([x0], [y0], s=50, color='b')

plt.annotate(r'$2x+1=%s$' % y0, xy=(x0, y0), xycoords='data',
             xytext=(+30, -30), textcoords='offset points',
             fontsize=16, arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=.2"))

plt.text(-2.7, 3, r'$Some\ example\ text\ with\ math\ \mu\ \sigma_i\ \alpha_t$',
         fontdict={'size': 16, 'color': 'r'})
plt.show()

Subplots: Irregular Layout

import matplotlib.pyplot as plt

plt.subplot(2, 1, 1)
plt.plot([0, 1], [0, 1])

plt.subplot(2, 3, 4)
plt.plot([0, 1], [0, 2])

plt.subplot(235)
plt.plot([0, 1], [0, 3])
plt.subplot(236)
plt.plot([0, 1], [0, 4])
plt.show()

Grid Layout with subplot2grid

import matplotlib.pyplot as plt

plt.figure()
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3)
ax1.plot([1, 2], [1, 2])
ax1.set_title('First Subplot')

ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))

ax4.scatter([1, 2], [2, 2])
ax4.set_xlabel('ax4_x')
ax4.set_ylabel('ax4_y')
plt.show()

Shared Axes

import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
axes[0, 0].scatter([1, 2], [1, 2])
plt.tight_layout()
plt.show()

Inset Plots

import matplotlib.pyplot as plt

fig = plt.figure()
x = [1, 2, 3, 4, 5, 6, 7]
y = [1, 3, 4, 2, 5, 8, 6]

ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax1.plot(x, y, 'r')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_title('Main Plot')

ax2 = fig.add_axes([0.2, 0.6, 0.25, 0.25])
ax2.plot(y, x, 'b')
ax2.set_title('Inset 1')

plt.axes([0.6, 0.2, 0.25, 0.25])
plt.plot(y[::-1], x, 'g')
plt.title('Inset 2')
plt.show()

Dual Y-Axes

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 10, 0.1)
y1 = 0.05 * x ** 2
y2 = -1 * y1

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

ax1.plot(x, y1, 'g-')
ax1.set_xlabel('X data')
ax1.set_ylabel('Y1 data', color='g')
ax2.plot(x, y2, 'b-')
ax2.set_ylabel('Y2 data', color='b')
plt.show()

Scatter Plots

import matplotlib.pyplot as plt
import numpy as np

n = 1024
X = np.random.normal(0, 1, n)
Y = np.random.normal(0, 1, n)
T = np.arctan2(Y, X)

plt.scatter(X, Y, s=75, c=T, alpha=.5)
plt.xlim(-1.5, 1.5)
plt.xticks(())
plt.ylim(-1.5, 1.5)
plt.yticks(())
plt.show()

Bar Charts

import matplotlib.pyplot as plt
import numpy as np

n = 12
X = np.arange(n)
Y1 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)
Y2 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)

plt.bar(X, +Y1, facecolor='#9999ff', edgecolor='white')
plt.bar(X, -Y2, facecolor='#ff9999', edgecolor='white')
plt.xlim(-.5, n)
plt.xticks(())
plt.ylim(-1.25, 1.25)
plt.yticks(())

for x, y in zip(X, Y1):
    plt.text(x + 0.05, y + 0.05, '%.2f' % y, ha='center', va='bottom')
for x, y in zip(X, Y2):
    plt.text(x + 0.05, -y - 0.05, '%.2f' % y, ha='center', va='top')
plt.show()

Histograms

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

size, scale = 1000, 10
commutes = pd.Series(np.random.gamma(scale, size=size) ** 1.5)
plt.hist(commutes, bins=20, rwidth=0.9, color='#607c8e')
plt.grid(True)
plt.title('Commute Times for 1,000 Commuters')
plt.xlabel('Counts')
plt.ylabel('Commute Time')
plt.grid(axis='y', alpha=0.75)
plt.show()

Pie Charts

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
labels = ['Entertainment', 'Childcare', 'Food', 'Mortgage', 'Transport', 'Other']
sizes = [2, 5, 12, 70, 2, 9]
explode = (0, 0, 0, 0.1, 0, 0)
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=150)
plt.title('Monthly Expenses - August')
plt.axis('equal')
plt.show()

Contour Plots

import matplotlib.pyplot as plt
import numpy as np

def f(x, y):
    return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)

n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)

plt.contourf(X, Y, f(X, Y), 8, alpha=.75, cmap=plt.cm.hot)
C = plt.contour(X, Y, f(X, Y), 8, colors='black', linewidth=.5)
plt.clabel(C, inline=True, fontsize=10)
plt.xticks(())
plt.yticks(())
plt.show()

Radar Charts

import matplotlib.pyplot as plt
import numpy as np

plt.polar(0.25 * np.pi, 20, "ro", lw=2)
plt.ylim(0, 100)
plt.show()
theta = np.array([0.25, 0.75, 1, 1.5, 0.25])
r = [20, 60, 40, 80, 20]
plt.polar(theta * np.pi, r, "r-", lw=2)
plt.ylim(0, 100)
plt.show()
plt.style.use('ggplot')
theta = np.array([0.25, 0.75, 1, 1.5, 0.25])
r = [20, 60, 40, 80, 20]
plt.polar(theta * np.pi, r, "r-", lw=1)
plt.fill(theta * np.pi, r, 'r', alpha=0.75)
plt.ylim(0, 100)
plt.grid(True)
plt.show()
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('ggplot')

values = [3.2, 2.1, 3.5, 2.8, 3, 4]
values_1 = [2.4, 3.1, 4.1, 1.9, 3.5, 2.3]
feature = ['Skill', 'Knowledge', 'Problem Solving', 'Service Quality', 'Teamwork', 'IQ']

N = len(values)
angles = np.linspace(0, 2 * np.pi, N, endpoint=False)

values = np.concatenate((values, [values[0]]))
angles = np.concatenate((angles, [angles[0]]))
values_1 = np.concatenate((values_1, [values_1[0]]))

fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
ax.plot(angles, values, 'o-', linewidth=2, label='Before')
ax.fill(angles, values, 'r', alpha=0.5)
ax.plot(angles, values_1, 'o-', linewidth=2, label='After')
ax.fill(angles, values_1, 'b', alpha=0.5)

ax.set_thetagrids(angles * 180 / np.pi, feature)
ax.set_ylim(0, 5)
plt.title('Employee Performance Review')
ax.grid(True)
plt.show()

3D Visualization

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = Axes3D(fig)

X = np.arange(-4, 4, 0.25)
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X ** 2 + Y ** 2)
Z = np.sin(R)

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'))
ax.contourf(X, Y, Z, zdir='z', offset=-1, cmap=plt.get_cmap('rainbow'))
plt.show()

Animaitons

from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np

fig, ax = plt.subplots()
x = np.arange(0, 2 * np.pi, 0.01)
line, = ax.plot(x, np.sin(x))

def animate(i):
    line.set_ydata(np.sin(x + i / 10.0))
    return line,

def init():
    line.set_ydata(np.sin(x))
    return line,

ani = animation.FuncAnimation(fig=fig, func=animate, frames=100,
                             init_func=init, interval=20, blit=False)
plt.show()

Waterfall Charts

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = True

x = np.array([1, 3, 5, 7, 9])
y1 = [0.5, 0.0, 1.4, 2.7, 1.5]
y2 = [0.4, 0.5, 0.3, 0.3, 0.4]
y3 = [20.66, 21.5, 23, 7, 24.5]
y4 = [0.7, 0.4, 2.2, 0.9, 0.7]
y5 = [3, 16, 12.2, 13.6, 10]

df = pd.DataFrame(np.array([y1, y2, y3, y4, y5]).T)
colors = ['#000000', 'orange', 'lightgray', 'orange', 'dodgerblue']
w = 0.2

fig, ax = plt.subplots(figsize=(12, 8), facecolor='cornsilk')

for i, c in enumerate(colors):
    ax.bar(x=x + w * i,
           bottom=df.iloc[:, :i].sum(axis=1) - 1,
           height=df[i],
           width=w, color=c)

for i, j in zip(x + w * 3, df.sum(axis=1)):
    ax.text(x=i, y=j, s=f'{j:.2f}', size=12, color='red', family='Arial')

ax.set_yticks(ticks=range(0, 110, 10))
ax.grid(axis='both', ls='--')
plt.show()

Tags: python matplotlib Data Visualization Plotting charts

Posted on Thu, 11 Jun 2026 17:27:12 +0000 by hideous