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

如何按关联Slot分组设置条形宽度绘制广播频谱图

问题描述

我们有一个包含广播介质数据的DataFrame:

MHzSlotdBdB_median
010Slot12020.5
120Slot12120.5
230Slot21919
340Slot31818
450Slot42119
560Slot41719
670Slot42019
780Slot52222
890Slot61919
9100Slot61919

字段说明:

  • MHz:载波频率
  • Slot:业务名称
  • dB:单载波测量值
  • dB_median:单业务中位数值

一个业务可对应多个载波(即一个Slot对应多个MHz),需要绘制同一Slot的多个连续载波合并为完整色块的频谱图,但当前代码只能按Slot给单个条形染色,每个载波都是独立色块,不符合需求。

最小可复现代码

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df_test = pd.DataFrame({
    "MHz":[10,20,30,40,50,60,70,80,90,100],
    "Slot":["Slot1","Slot1","Slot2","Slot3","Slot4",
            "Slot4","Slot4","Slot5","Slot6","Slot6"],
    "dB":[20,21,19,18,21,17,20,22,19,19],
    "dB_median":[20.5,20.5,19,18,19,19,19,22,19,19]
})

plt.figure(figsize=(8,4))
g = sns.barplot(
    data=df_test,
    x="MHz",
    y="dB_median",
    hue="Slot"
)
sns.move_legend(g, "lower center", ncol=6, bbox_to_anchor=(0.5, 1))
plt.show()
实现思路与解决方案

核心思路

放弃seaborn的条形图,直接用matplotlib绘制矩形色块:

  1. 按Slot分组,计算每个业务的频率区间(最小/最大MHz)和对应的中位值
  2. 用matplotlib.patches.Rectangle绘制覆盖整个频率区间的连续色块
  3. 可选叠加单载波的实际测量值作为标记

修改后的代码示例

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.lines import Line2D

df_test = pd.DataFrame({
    "MHz":[10,20,30,40,50,60,70,80,90,100],
    "Slot":["Slot1","Slot1","Slot2","Slot3","Slot4",
            "Slot4","Slot4","Slot5","Slot6","Slot6"],
    "dB":[20,21,19,18,21,17,20,22,19,19],
    "dB_median":[20.5,20.5,19,18,19,19,19,22,19,19]
})

# 分组计算每个Slot的频率范围、中位值和对应颜色
slot_groups = df_test.groupby("Slot").agg(
    min_mhz=("MHz", "min"),
    max_mhz=("MHz", "max"),
    median_db=("dB_median", "first"),
    color=("Slot", lambda x: plt.cm.tab10(df_test["Slot"].unique().tolist().index(x.iloc[0])))
).reset_index()

plt.figure(figsize=(8,4))
ax = plt.gca()

freq_width = df_test["MHz"].diff().dropna().unique()[0]  # 获取载波间隔(此处为10MHz)

# 绘制每个Slot的连续色块
for _, row in slot_groups.iterrows():
    # 调整矩形位置和宽度,确保覆盖所有对应载波
    rect = Rectangle(
        (row["min_mhz"] - freq_width/2, 0),
        row["max_mhz"] - row["min_mhz"] + freq_width,
        row["median_db"],
        color=row["color"],
        alpha=0.7
    )
    ax.add_patch(rect)

# 叠加单载波测量值(可选)
ax.scatter(df_test["MHz"], df_test["dB"], color="black", zorder=5)

# 设置坐标轴参数
ax.set_xlim(df_test["MHz"].min() - freq_width/2, df_test["MHz"].max() + freq_width/2)
ax.set_ylim(0, df_test["dB"].max() + 2)
ax.set_xlabel("MHz")
ax.set_ylabel("dB")

# 自定义图例
slot_legends = [Line2D([0], [0], color=row["color"], lw=4, label=row["Slot"]) for _, row in slot_groups.iterrows()]
measure_legend = Line2D([0], [0], marker='o', color='w', markerfacecolor='black', label='单载波测量值')
ax.legend(handles=slot_legends + [measure_legend], loc="lower center", ncol=6, bbox_to_anchor=(0.5, 1))

plt.tight_layout()
plt.show()

关键说明

  • 计算频率区间时,需结合载波间隔调整矩形位置,避免色块间出现间隙
  • 使用内置配色tab10自动分配Slot颜色,也可自定义颜色映射
  • 散点标记可按需添加,用于展示单载波的实际测量值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:45:19