Matplotlib实现X轴与Y轴双轴断裂的技术求助
实现Matplotlib双轴断裂(Y轴+X轴)及红色斜杠标记
以下是修改后的完整代码,同时实现Y轴(8-36)和X轴(2-5)的断裂效果,并用红色斜杠标记X轴的断裂区域:
import matplotlib.pyplot as plt import numpy as np # 定义数据 xAxis = [0.5, 1, 2, 5] data = { 'apples': [41.99, 41.99, 41.99, 61.99], 'bananas': [39.99, 39.99, 39.99, 39.99], 'cucumbers': [0.02, 0.02, 0.40, 0.10], 'dill': [0.04, 0.04, 0.08, 0.2], 'eel': [0.08, 0.08, 0.16, 0.40], 'figs': [0.99, 1.50, 3.00, 4.00], 'grapes': [1.50, 1.50, 6.00, 6.00] } # 创建2行2列的子图布局,实现双轴断裂的基础结构 fig, ((ax_top_left, ax_top_right), (ax_bot_left, ax_bot_right)) = plt.subplots(2, 2, figsize=(10, 8)) ax_list = [ax_top_left, ax_top_right, ax_bot_left, ax_bot_right] # 批量绘制所有数据,减少重复代码 for ax in ax_list: for label, y_data in data.items(): ax.scatter(xAxis, y_data, label=label) # -------------------------- Y轴断裂设置 -------------------------- # 上排子图展示高价区间(36-64) ax_top_left.set_ylim(36, 64) ax_top_right.set_ylim(36, 64) # 下排子图展示低价区间(0-8) ax_bot_left.set_ylim(0, 8) ax_bot_right.set_ylim(0, 8) # 隐藏上下子图之间的连接脊柱 ax_top_left.spines['bottom'].set_visible(False) ax_top_right.spines['bottom'].set_visible(False) ax_bot_left.spines['top'].set_visible(False) ax_bot_right.spines['top'].set_visible(False) # 绘制Y轴断裂的黑色斜杠 d_y = 0.015 kwargs_y = dict(transform=ax_top_left.transAxes, color='k', clip_on=False) ax_top_left.plot((-d_y, +d_y), (-d_y, +d_y), **kwargs_y) ax_top_right.plot((1-d_y, 1+d_y), (-d_y, +d_y), **kwargs_y) kwargs_y.update(transform=ax_bot_left.transAxes) ax_bot_left.plot((-d_y, +d_y), (1-d_y, 1+d_y), **kwargs_y) ax_bot_right.plot((1-d_y, 1+d_y), (1-d_y, 1+d_y), **kwargs_y) # -------------------------- X轴断裂设置 -------------------------- # 左列子图展示X轴0-2区间 ax_top_left.set_xlim(-0.1, 2.1) ax_bot_left.set_xlim(-0.1, 2.1) # 右列子图聚焦X轴5附近的点 ax_top_right.set_xlim(4.9, 5.1) ax_bot_right.set_xlim(4.9, 5.1) # 隐藏左右子图之间的连接脊柱 ax_top_left.spines['right'].set_visible(False) ax_bot_left.spines['right'].set_visible(False) ax_top_right.spines['left'].set_visible(False) ax_bot_right.spines['left'].set_visible(False) # 绘制X轴断裂的红色双斜杠,替代黄色高亮区域 d_x = 0.025 kwargs_x = dict(transform=ax_top_left.transAxes, color='red', clip_on=False, linewidth=1.5) ax_top_left.plot((1-d_x, 1+d_x), (-d_x, +d_x), **kwargs_x) ax_top_left.plot((1-d_x, 1+d_x), (1-d_x, 1+d_x), **kwargs_x) kwargs_x.update(transform=ax_top_right.transAxes) ax_top_right.plot((-d_x, +d_x), (-d_x, +d_x), **kwargs_x) ax_top_right.plot((-d_x, +d_x), (1-d_x, 1+d_x), **kwargs_x) kwargs_x.update(transform=ax_bot_left.transAxes) ax_bot_left.plot((1-d_x, 1+d_x), (-d_x, +d_x), **kwargs_x) ax_bot_left.plot((1-d_x, 1+d_x), (1-d_x, 1+d_x), **kwargs_x) kwargs_x.update(transform=ax_bot_right.transAxes) ax_bot_right.plot((-d_x, +d_x), (-d_x, +d_x), **kwargs_x) ax_bot_right.plot((-d_x, +d_x), (1-d_x, 1+d_x), **kwargs_x) # -------------------------- 刻度与标签优化 -------------------------- # 上排子图隐藏X轴刻度,下排显示对应刻度 ax_top_left.tick_params(labelbottom=False, bottom=False) ax_top_right.tick_params(labelbottom=False, bottom=False) ax_bot_left.set_xticks([0, 0.5, 1, 2]) ax_bot_right.set_xticks([5]) # 设置全局轴标签,避免重复 fig.text(0.5, 0.02, 'Plan Size', ha='center', fontsize=12) fig.text(0.06, 0.5, 'Cost in USD', va='center', rotation='vertical', fontsize=12) # 设置标题与图例位置 ax_top_left.set_title('Food spend', loc='center', fontsize=14) ax_top_right.legend(loc='upper right', bbox_to_anchor=(1.15, 1), shadow=True) # 调整子图间距,保证断裂标记显示连贯 plt.subplots_adjust(wspace=0.05, hspace=0.05) plt.show()
关键修改说明:
- 子图结构重构:采用2行2列的子图布局,分别对应Y轴的高低价区间和X轴的前后区间,同时实现双轴断裂效果。
- X轴断裂标记:在左右子图衔接处绘制红色双斜杠,精准替代原需求中的黄色高亮区域,使用
transAxes坐标确保标记位置不受轴范围变化影响。 - 脊柱隐藏优化:隐藏所有子图之间的多余脊柱,让断裂视觉效果更自然。
- 代码精简:将数据整理为字典,通过循环批量绘制散点图,减少重复代码量。
- 布局调整:通过
subplots_adjust缩小子图间距,保证断裂标记的连贯性,同时统一设置全局轴标签提升图表整洁度。
内容的提问来源于stack exchange,提问作者marscolonizer
相关产品推荐
相关产品推荐

