【Matplotlib学习】Matplotlib 中 x 轴和 y 轴的玩法大全:从基础到高级技巧

Matplotlib 中 x 轴和 y 轴的玩法大全:从基础到高级技巧

Matplotlib 的坐标轴系统是其强大功能的核心,提供了丰富的定制选项。本文将全面总结 x 轴和 y 轴的各种玩法,并详细比较子图级别与整图级别的设置差异。

一、x 轴和 y 轴的基础玩法

(一)轴的范围和刻度控制

import matplotlib.pyplot as plt
import numpy as np

# 设置轴范围
plt.xlim(0, 10)  # 设置 x 轴范围
plt.ylim(-5, 5)  # 设置 y 轴范围

# 或者使用面向对象方式
ax.set_xlim(0, 10)
ax.set_ylim(-5, 5)

# 自动调整范围
ax.autoscale(enable=True, axis='x', tight=True)

# 设置刻度位置
plt.xticks([0, 2, 4, 6, 8, 10])  # 指定 x 轴刻度位置
plt.yticks(np.arange(-5, 6, 1))  # 指定 y 轴刻度位置

# 设置刻度标签
plt.xticks([0, 5, 10], ['Start', 'Middle', 'End'])  # 自定义刻度标签

# 设置刻度间隔
from matplotlib.ticker import MultipleLocator
ax.xaxis.set_major_locator(MultipleLocator(2))  # 主刻度每 2 个单位
ax.xaxis.set_minor_locator(MultipleLocator(0.5))  # 次刻度每 0.5 个单位

(二)轴标签和标题

# 设置轴标签
plt.xlabel('X Axis Label', fontsize=12, color='blue')
plt.ylabel('Y Axis Label', fontsize=12, color='red')

# 设置轴标题
ax.set_xlabel('X Axis Label', fontdict={'fontsize': 12, 'fontweight': 'bold'})
ax.set_ylabel('Y Axis Label', fontdict={'fontsize': 12, 'fontweight': 'bold'})

# 旋转标签
plt.xticks(rotation=45)  # x 轴标签旋转 45 度

(三)轴刻度格式化和样式

# 科学计数法格式化
from matplotlib.ticker import ScalarFormatter
ax.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))

# 百分比格式化
from matplotlib.ticker import PercentFormatter
ax.yaxis.set_major_formatter(PercentFormatter(1.0))  # 1.0 = 100%

# 日期格式化
import matplotlib.dates as mdates
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

# 对数刻度
ax.set_xscale('log')  # 设置 x 轴为对数刻度
ax.set_yscale('log')  # 设置 y 轴为对数刻度

# 对称对数刻度(处理正负值)
ax.set_yscale('symlog', linthresh=0.01)  # 在 0.01 附近使用线性刻度

(四)轴线和刻度样式

# 设置轴线颜色和宽度
ax.spines['bottom'].set_color('blue')
ax.spines['bottom'].set_linewidth(2)
ax.spines['left'].set_color('red')
ax.spines['left'].set_linewidth(2)

# 隐藏上部和右侧轴线
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# 设置刻度方向、长度和颜色
ax.tick_params(axis='x', direction='out', length=6, width=2, color='blue')
ax.tick_params(axis='y', direction='in', length=10, width=1, color='red')

# 设置刻度标签颜色和大小
ax.tick_params(axis='x', labelsize=10, labelcolor='green')

二、高级轴玩法

(一)双轴和共享轴

# 创建双 y 轴
ax2 = ax.twinx()  # 共享 x 轴,创建新 y 轴
ax2.plot(x, y2, 'r-')
ax2.set_ylabel('Second Y Axis')

# 创建双 x 轴
ax3 = ax.twiny()  # 共享 y 轴,创建新 x 轴
ax3.plot(x2, y, 'g-')
ax3.set_xlabel('Second X Axis')

# 共享轴(多个子图)
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)  # 共享 x 轴
fig, (ax1, ax2) = plt.subplots(1, 2, sharey=True)  # 共享 y 轴

(二)轴位置和方向

# 移动轴位置
ax.spines['bottom'].set_position(('data', 0))  # 将 x 轴移动到 y=0 的位置
ax.spines['left'].set_position(('data', 0))    # 将 y 轴移动到 x=0 的位置

# 反转轴方向
ax.invert_xaxis()  # 反转 x 轴
ax.invert_yaxis()  # 反转 y 轴

# 设置轴原点位置
ax.spines['left'].set_position('zero')  # 将 y 轴移动到 x=0
ax.spines['bottom'].set_position('zero')  # 将 x 轴移动到 y=0

(三)自定义刻度和网格

# 自定义刻度格式化函数
def custom_formatter(x, pos):
    if x >= 1000:
        return f'{x/1000:.0f}k'
    else:
        return f'{x:.0f}'

ax.xaxis.set_major_formatter(plt.FuncFormatter(custom_formatter))

# 添加网格
ax.grid(True, which='major', linestyle='-', linewidth=0.5, color='gray', alpha=0.5)
ax.grid(True, which='minor', linestyle=':', linewidth=0.5, color='lightgray', alpha=0.3)

# 设置网格只在主要或次要刻度上显示
ax.xaxis.grid(True, which='major')
ax.yaxis.grid(True, which='minor')

(四)轴限制和自动缩放

# 动态调整轴范围
margin = 0.1  # 10% 的边距
x_margin = (x_max - x_min) * margin
y_margin = (y_max - y_min) * margin
ax.set_xlim(x_min - x_margin, x_max + x_margin)
ax.set_ylim(y_min - y_margin, y_max + y_margin)

# 保持纵横比
ax.set_aspect('equal')  # 1:1 纵横比
ax.set_aspect(2)        # x 轴单位长度是 y 轴的 2 倍

# 自动缩放但保持特定范围
ax.set_autoscale_on(True)
ax.set_ylim(bottom=0)  # y 轴从 0 开始,但自动调整上限

三、子图与整幅图的轴设置差异

(一)设置级别的差异

设置类型子图级别 (Axes)整图级别 (Figure)
轴范围ax.set_xlim(), ax.set_ylim()无直接设置,但可通过布局调整影响
轴标签ax.set_xlabel(), ax.set_ylabel()fig.supxlabel(), fig.supylabel() (Matplotlib 3.4+)
轴刻度ax.set_xticks(), ax.set_yticks()无直接设置
刻度标签ax.set_xticklabels(), ax.set_yticklabels()无直接设置
轴标题ax.set_title()fig.suptitle()
共享轴ax.sharex(), ax.sharey()创建子图时通过 sharex, sharey 参数

(二)实际应用中的区别

# 创建子图
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

# 子图级别的设置(只影响当前子图)
axes[0, 0].set_xlim(0, 10)
axes[0, 0].set_xlabel('X for subplot 1')

# 整图级别的设置(影响所有子图)
fig.suptitle('Overall Figure Title')  # 整图标题
fig.supxlabel('Common X Label')       # 整图 x 轴标签 (Matplotlib 3.4+)
fig.supylabel('Common Y Label')       # 整图 y 轴标签 (Matplotlib 3.4+)

# 批量设置所有子图
for ax in axes.flat:
    ax.set_xlim(0, 10)  # 统一设置所有子图的 x 轴范围
    ax.tick_params(axis='x', rotation=45)  # 统一旋转 x 轴标签

# 共享轴设置(创建时)
fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)  # 所有子图共享轴

# 共享轴设置(创建后)
axes[0, 0].sharex(axes[1, 0])  # 特定子图之间共享轴

(三)布局调整的影响

# 整图级别的布局调整会影响所有子图的轴位置
plt.subplots_adjust(
    left=0.1,      # 左边距
    bottom=0.1,    # 底边距
    right=0.9,     # 右边距
    top=0.9,       # 顶边距
    wspace=0.2,    # 子图之间水平间距
    hspace=0.3     # 子图之间垂直间距
)

# 使用 constrained_layout 自动调整
fig, axes = plt.subplots(2, 2, constrained_layout=True)

# 使用 GridSpec 进行精细控制
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(2, 2, width_ratios=[1, 2], height_ratios=[2, 1])
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])  # 跨两列

四、实用技巧和最佳实践

(一)处理日期轴

import pandas as pd
import matplotlib.dates as mdates

# 创建日期数据
dates = pd.date_range('2023-01-01', '2023-12-31', freq='D')
values = np.random.randn(len(dates)).cumsum()

# 绘制日期数据
fig, ax = plt.subplots()
ax.plot(dates, values)

# 设置日期格式
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax.xaxis.set_major_locator(mdates.MonthLocator())
plt.xticks(rotation=45)

(二)处理分类数据轴

# 分类数据
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 12, 78]

fig, ax = plt.subplots()
ax.bar(categories, values)

# 自定义分类轴标签
ax.set_xticks(range(len(categories)))
ax.set_xticklabels([f'Category {c}' for c in categories], rotation=45)

(三)高级轴装饰

# 添加轴箭头
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.plot(1, 0, ">k", transform=ax.get_yaxis_transform(), clip_on=False)
ax.plot(0, 1, "^k", transform=ax.get_xaxis_transform(), clip_on=False)

# 添加轴背景色
ax.axhspan(ymin=0, ymax=1, facecolor='green', alpha=0.1)  # 水平背景区域
ax.axvspan(xmin=0, xmax=1, facecolor='blue', alpha=0.1)   # 垂直背景区域

(四)响应式轴调整

# 自动调整标签避免重叠
fig, ax = plt.subplots()
ax.plot(x, y)
fig.autofmt_xdate()  # 自动旋转日期标签

# 动态调整刻度密度基于图形大小
def update_ticks(ax, fig):
    # 根据图形大小调整刻度密度
    width = fig.get_figwidth() * fig.dpi
    height = fig.get_figheight() * fig.dpi
    
    # 计算合适的刻度数量
    x_ticks = max(5, int(width / 100))
    y_ticks = max(5, int(height / 80))
    
    ax.xaxis.set_major_locator(plt.MaxNLocator(x_ticks))
    ax.yaxis.set_major_locator(plt.MaxNLocator(y_ticks))

# 连接调整函数
fig.canvas.mpl_connect('resize_event', lambda event: update_ticks(ax, fig))

五、总结表格:子图与整图轴设置对比

功能子图级别 (Axes)整图级别 (Figure)说明
轴范围set_xlim(), set_ylim()无直接方法整图可通过布局调整间接影响
轴标签set_xlabel(), set_ylabel()supxlabel(), supylabel()整图方法需要 Matplotlib 3.4+
轴标题set_title()suptitle()整图标题显示在所有子图上方
刻度位置set_xticks(), set_yticks()无直接方法
刻度标签set_xticklabels(), set_yticklabels()无直接方法
刻度格式xaxis.set_major_formatter()无直接方法
共享轴sharex(), sharey()创建时通过参数设置整图级别设置更简洁
轴线样式spines[] 相关方法无直接方法
网格线grid()无直接方法
布局调整subplots_adjust(), tight_layout()整图级别控制所有子图位置
### 寻找有趣的Python编程项目创意玩法 #### 吃金币小游戏 创建一个简单的吃金币游戏是一个很好的入门级项目。该游戏涉及基本的图形界面设计以及事件处理机制。玩家控制一个小角色,在二维网格上移动并收集散落在各处的金币。此过程不仅能够加深对循环结构的理解,还能锻炼解决问题的能力[^2]。 ```python import pygame from random import randint pygame.init() screen = pygame.display.set_mode((800, 600)) player_img = pygame.image.load('player.png') coin_img = pygame.image.load('coin.png') def draw_player(x, y): screen.blit(player_img, (x, y)) def draw_coin(cx, cy): screen.blit(coin_img, (cx, cy)) running = True px, py = 400, 300 cx, cy = randint(50, 750), randint(50, 550) while running: screen.fill((255, 255, 255)) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: px -= 1 elif keys[pygame.K_RIGHT]: px += 1 distance = ((px-cx)**2 + (py-cy)**2)**0.5 if distance < 27: cx, cy = randint(50, 750), randint(50, 550) draw_player(px, py) draw_coin(cx, cy) pygame.display.update() pygame.quit() ``` #### 动态可视化图表制作 利用`matplotlib`库中的动画功能模块,可以实现数据随时间变化而更新的效果,并最终导出为GIF文件。这类应用广泛存在于金融分析、气象预报等领域之中。通过编写脚本来抓取实时数据并将其转化为直观易懂的画面展示给用户[^3]。 ```python import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation import numpy as np fig, ax = plt.subplots() def animate(frame_num): data = np.random.rand(10) * frame_num / 10. ax.clear() ax.plot(data) ani = FuncAnimation(fig=fig, func=animate, frames=np.arange(0, 10), interval=500) plt.show() ``` #### 自动化任务执行器 构建一系列实用性强的小工具来简化日常操作流程。比如定时提醒喝水休息的应用程序;批量重命名图片文档名称的批处理命令等等。这些小型应用程序虽然看似简单却能极大提高工作效率。 ```bash # 批量修改文件名示例(Linux/MacOS) for file in *.jpg; do mv "$file" "${file%.jpg}_new.jpg"; done ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值