You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Matplotlib中构建双向条形图:变量居中与百分比轴设置

双向条形图实现方案

下面是针对你的需求的完整实现代码,解决level垂直居中显示和X轴百分比格式化的问题,同时修正了DataFrame中variable列大小写不一致的问题(比如Exam和exam会被识别为不同分组,先统一处理):

步骤1:数据预处理

首先统一variable列的大小写,避免分组错误:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

# 构造你的DataFrame
data = [
    ["volfluid", "1L", 0.718, 0.690],
    ["volfluid", "2L", 0.501, 0.808],
    ["volfluid", "5L", 0.181, 0.920],
    ["MAP", "64", 0.434, 0.647],
    ["MAP", "58", 0.477, 0.854],
    ["MAP", "52", 0.489, 0.904],
    ["Exam", "dry", 0.668, 0.713],
    ["exam", "euvolemic", 0.475, 0.798],
    ["exam", "wet", 0.262, 0.893],
    ["pmh", "COPD", 0.506, 0.804],
    ["pmh", "Kidney", 0.441, 0.778],
    ["pmh", "HF", 0.450, 0.832],
    ["Case", "1 (PIV)", 0.435, 0.802],
    ["Case", "2 (CVC)", 0.497, 0.809]
]
df = pd.DataFrame(data, columns=["variable", "level", "margins_fluid", "margins_vp"])

# 统一variable列的大小写,避免分组错误
df["variable"] = df["variable"].str.lower()

步骤2:绘图实现

# 按variable分组,计算每个组的y轴位置范围
grouped = df.groupby("variable")
y_positions = []
current_y = 0
group_spacing = 2  # 组之间的间距
level_spacing = 1  # 同组内level的间距

# 先计算所有y位置
for name, group in grouped:
    n_levels = len(group)
    # 分配当前组内每个level的y位置
    group_y = list(range(current_y, current_y + n_levels * level_spacing, level_spacing))
    y_positions.extend(group_y)
    current_y += n_levels * level_spacing + group_spacing

# 初始化画布
plt.figure(figsize=(12, 10))

# 绘制左向条形(margins_fluid,取负值)
plt.barh(y_positions, -df["margins_fluid"], height=0.6, color="#1f77b4", label="Fluid Margin")
# 绘制右向条形(margins_vp)
plt.barh(y_positions, df["margins_vp"], height=0.6, color="#ff7f0e", label="VP Margin")

# 添加level标签(垂直居中显示)
for y, level in zip(y_positions, df["level"]):
    plt.text(0, y, level, ha="center", va="center", fontsize=10, rotation=90)

# 设置X轴为百分比格式
def to_percent(x, pos):
    return f"{abs(x)*100:.0f}%"
formatter = FuncFormatter(to_percent)
plt.gca().xaxis.set_major_formatter(formatter)

# 添加分组标题(显示在每组的上方)
current_y = 0
for name, group in grouped:
    n_levels = len(group)
    group_center = current_y + (n_levels - 1)*level_spacing / 2
    plt.text(-1.2, group_center, name.capitalize(), ha="center", va="center", fontsize=12, fontweight="bold")
    current_y += n_levels * level_spacing + group_spacing

# 设置X轴范围,留出足够空间显示分组标题
plt.xlim(-1.3, 1.3)

# 添加图例、网格
plt.legend()
plt.grid(axis="x", linestyle="--", alpha=0.7)
plt.tick_params(axis="y", left=False, labelleft=False)  # 隐藏原y轴刻度
plt.title("Bidirectional Bar Chart with Centered Level Labels", fontsize=14)

plt.tight_layout()
plt.show()

关键说明

  • level居中显示:通过手动计算每个level的y轴位置,在X=0的位置添加垂直旋转的文本,实现居中效果;同时隐藏原y轴刻度,避免干扰。
  • X轴百分比转换:使用FuncFormatter自定义格式化函数,将小数转换为带百分号的字符串,同时处理左向条形的负值(取绝对值显示)。
  • 分组间距控制:通过group_spacing和level_spacing参数调整组间和组内的垂直间距,让图表更清晰。

内容的提问来源于stack exchange,提问作者hulio_entredas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 16:02:58