Python嵌套绘图并为条形图添加自定义标注

论文绘图时经常需要多图嵌套,正好最近绘图用到了,记录一下使用Python实现多图嵌套的过程。

首先,实现 Seaborn 分别绘制折线图和柱状图。

python 复制代码
'''绘制折线图'''
import seaborn as sns
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore", "use_inf_as_na")

# 获取绘图数据
df_fmri=sns.load_dataset("fmri")
# 绘制折线图
sns.lineplot(data=df_fmri, x="timepoint", y="signal", hue="event")

# 创建绘图数据
df_bar=df_fmri[['subject','signal']].groupby('subject',observed=True).agg('max').reset_index()
# 绘制条形图
ax_bar=sns.barplot(
    data=df_bar,
    x="subject", y="signal",
    palette='Set2',
)

接下来实现条形图与折线图的嵌套,核心是使用 inset_axes 函数创建一个新的轴,然后再绘制第二个图时指定绘图的轴为刚才新建的轴。

python 复制代码
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import matplotlib.pyplot as plt

# 获取绘图数据
df_fmri = sns.load_dataset("fmri")
df_bar=df_fmri[['subject','signal']].groupby('subject',observed=True).agg('max').reset_index()

# 绘制折线图
ax=sns.lineplot(data=df_fmri, x="timepoint", y="signal", hue="event")
plt.legend(loc='upper left')

# 使用 inset_axes 函数添加一个轴,用来显示条形图
ax_bar = inset_axes(
    ax, # 父轴
    width='40%', height='50%', # 新轴相对于父轴的长宽比例
    loc='lower left', # 新轴的锚点相对于父轴的位置
    bbox_to_anchor=(0.55,0.45,1,1), # 新轴的bbox
    bbox_transform=ax.transAxes # bbox_to_anchor 的坐标基准
    )
# 绘制条形图
ax_bar=sns.barplot(
    data=df_bar,
    x="subject", y="signal", 
    palette='Set2',
    ax=ax_bar
)

可以看到,右上角的条形图显得很拥挤,x轴标注相互重叠比较严重,因此,考虑将条形图由纵向变为横向,在 Seaborn 绘图时交换 x 轴和 y 轴就能实现。此外,bar上方的空间也比较大,考虑将x轴的标注标注到bar上方,以进一步节约空间。bar的标注可以通过 ax.bar_label() 函数实现,该函数不仅可以直接标注每个bar的数值,也可以自定义要标注的内容和格式。修改后的代码和结果图如下:

python 复制代码
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import matplotlib.pyplot as plt

# 准备数据
df_fmri = sns.load_dataset("fmri")
df_bar=df_fmri[['subject','signal']].groupby('subject',observed=True).agg('max').reset_index()

# 绘制折线图
ax=sns.lineplot(data=df_fmri, x="timepoint", y="signal", hue="event")
plt.legend(loc='upper left')

# 使用 inset_axes 函数添加一个轴,用来显示条形图
ax_bar = inset_axes(
    ax, # 父轴
    width='47%', height='52%', # 新轴相对于父轴的长宽比例
    loc='lower left', # 新轴的锚点相对于父轴的位置
    bbox_to_anchor=(0.5,0.44,1,1), # 新轴的bbox
    bbox_transform=ax.transAxes # bbox_to_anchor 的坐标基准
    )
# 绘制条形图
ax_bar=sns.barplot(
    data=df_bar,
    # 交换 x 轴和 y 轴列名实现横向条形图
    x="signal", y="subject", 
    palette='Set2',
    ax=ax_bar
)
# 使用 sns 的 bar_label 函数为条形图添加标注
ax_bar.bar_label(
    ax_bar.containers[0], # 条形图的 BarContainer 对象
    labels=df_bar['subject'], # 要标注的labels,默认为 bar 的数值,此处传入自定义的label序列
    label_type='edge', # 标注显示的位置,可选 edge 或 center
    padding=2, # 标注与bar之间的距离
    # fmt='%.2f' # 标注格式化字符串
    fontsize=10 # 设置标注的字体大小
    )
# 为了避免标注超出绘图范围,将x轴的绘图范围扩大
plt.xlim(0,0.62)
# 隐藏左侧y轴
ax_bar.yaxis.set_visible(False)
# 去除多余的轴线
sns.despine()

打完收工!

相关推荐
2601_962298272 分钟前
Python与Selenium结合的Web自动化测试全流程实践教程
自动化测试·python·selenium·web测试·pageobjectmodel
天衍四九-23 分钟前
第一章:从 LLM 到 Agent —— DeepSeek Harness 入门
网络·数据库·人工智能·python
529宝宝起名网25 分钟前
用 Python 实现名字寓意评分算法:基于 NLP 语义分析的名字内涵深度评估
python·算法·自然语言处理
2601_9622986731 分钟前
Python:对象缓存优化机制(CPython)
python·性能优化·内存优化·cpython·对象缓存
枫彩1 小时前
A股数据源怎么选?用 Python 验收 AI 复盘的日期与明细
python·ai agent·股票数据·mcp
2601_962382431 小时前
Python 代码不可不知的函数式编程技术
python·函数式编程·高阶函数·嵌套函数·头等函数
2601_962078031 小时前
Python办公自动化与数据分析实战 培训班2021年
python·数据分析·办公自动化·自动化办公·实战演练
用户938515635072 小时前
Text2SQL 实战:用 DeepSeek 大模型实现自然语言查询 SQLite 数据库
python·sqlite
2601_962099682 小时前
Python环境下中文分词实现与应用探索
python·自然语言处理·中文分词·jieba·开源社区
2601_966949652 小时前
批量获取多只股票五档盘口的极简方案:QuantDash Python SDK 实战指南
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash