哑铃图:数据对比的优雅之选合集 - 数据可视化(66)
哑铃图是什么哑铃图Dumbbell Plot有时也称为DNA图或杠铃图是一种用于比较两个相关数据点的可视化图表。它源于人们对更有效数据比较方式的持续探索。在传统的时间序列比较中我们通常使用两条折线但当需要比较的项目较多时折线图会变得混乱。哑铃图通过将比较焦点放在每个项目的两个状态上解决了多项目对比时的视觉混乱问题。它的基本结构很简单每个观察单位如产品、地区、时间段对应两个数据点这两个数据点由一条直线或线段连接整个图形看起来像一排排哑铃因而得名2. 实现原理哑铃图的核心设计理念是最小化认知负荷。当我们需要比较A和B时最直接的方式就是把它们放在一起用一条线连接然后观察这条线的长度差异大小和方向哪个更大。在matplotlib中创建哑铃图我们主要使用以下元素散点图表示两个数据点直线段连接两个相关点颜色编码通常用不同颜色区分前后状态或不同组别标签系统清晰标识每个观察单位3. 实战示例接下来我们看看哑铃图在实际场景中的显示效果。假设我们是一家电商公司的数据分析师需要比较8个主要产品类别在2022年和2023年的销售额变化。完整的代码在文章末尾提供下载地址文中只截取部分代码先创建一些测试数据# 示例数据8个产品类别在2022年和2023年的销售额单位万元 categories [ 电子产品, 服装鞋帽, 家居用品, 美妆护肤, 图书音像, 运动户外, 食品饮料, 母婴用品, ] sales_2022 [85, 92, 78, 65, 45, 60, 88, 72] sales_2023 [95, 87, 85, 78, 52, 73, 95, 80]然后我们绘制传统的簇状条形图和哑铃图来对比一下效果# 创建子图对比两种可视化方法 fig, (ax1, ax2) plt.subplots(1, 2, figsize(14, 8)) # 簇状条形图 x np.arange(len(categories)) bars1 ax1.bar(x - width/2, sales_2022, width, label2022年, color#4C72B0, alpha0.8) bars2 ax1.bar(x width/2, sales_2023, width, label2023年, color#DD8452, alpha0.8) # 在每个条形上添加数值标签 # 省略 ... # 哑铃图 # 设置y轴位置每个类别的垂直位置 y_pos np.arange(len(categories)) # 绘制连接线 for i, (y2022, y2023) in enumerate(zip(sales_2022, sales_2023)): # 确定线颜色增长为绿色下降为红色 line_color #55A868 if y2023 y2022 else #C44E52 ax2.plot([y2022, y2023], [i, i], colorline_color, linewidth2.5, alpha0.7, zorder1) # 绘制数据点 ax2.scatter(sales_2022, y_pos, s120, color#4C72B0, alpha0.9, label2022年, zorder2, edgecolorswhite, linewidth2) ax2.scatter(sales_2023, y_pos, s120, color#DD8452, alpha0.9, label2023年, zorder2, edgecolorswhite, linewidth2) # 省略 ... plt.tight_layout() plt.show()通过上面的对比我们可以清晰地看到哑铃图的优势变化一目了然连接线的长度直观表示变化幅度方向表示增长或下降减少视觉跳跃眼睛不需要在条形间来回移动而是沿着水平线自然追踪突出比较重点专注于每个项目的两个状态对比而非绝对数值进一步我们还可以给哑铃图排序按照增长由快到慢给各个品类排序这样自然形成从下降最显著到增长最显著的连续谱模式自动显现无需刻意寻找。比如上面的哑铃图中【服装鞋帽】这个品类其实销售额是下降的混在一堆哑铃中不容易看出来吧# 创建排序后的哑铃图 fig, ax plt.subplots(figsize(10, 8)) # 按变化幅度排序 sorted_indices np.argsort( [sales_2023[i] - sales_2022[i] for i in range(len(categories))] ) sorted_categories [categories[i] for i in sorted_indices] sorted_2022 [sales_2022[i] for i in sorted_indices] sorted_2023 [sales_2023[i] for i in sorted_indices] # 绘制连接线 # 省略 ... # 绘制数据点 # 省略 ... # 添加变化箭头标注 # 省略 ... plt.tight_layout() plt.show()这样改造后由上到下的哑铃越来越短也就是增长越来越慢最底部的那个是负增长用了红色来标注。4. 总结数据可视化的核心目标是有效传达信息。当我们需要强调变化、比较两个相关状态时哑铃图提供了一种简洁而强大的解决方案。就像选择合适的工具完成工作一样在面对数据比较任务时我们应该根据具体需求选择最合适的可视化形式当需要比较多个项目的两个状态时选择哑铃图当需要展示单个项目的多个组成部分时选择堆积条形图当需要比较多个项目的多个类别时选择簇状条形图最好的可视化不是最复杂的而是能让观众在最短时间内理解最多信息的那个。

相关新闻

SAP PS模块实战:手把手教你用BAPI批量创建WBS和项目(附透明表查询技巧)

SAP PS模块实战:手把手教你用BAPI批量创建WBS和项目(附透明表查询技巧)

SAP PS模块实战:BAPI批量创建WBS与透明表查询全攻略在装备制造和能源工程这类大型项目中,手动逐个创建WBS元素就像用勺子挖运河——理论上可行,但实操中会让你怀疑人生。作为经历过数十个SAP PS模块实施的顾问,我总结出一套高效可…

2026/7/1 6:07:25阅读更多 →
北京到长白山没有直达高铁

北京到长白山没有直达高铁

先交代一下背景。我们3组家庭,都是北京海淀的,孩子从6岁到10岁不等,平时在同一个小区里玩,暑假想一起带娃出去走走。商量来商量去,最后选定了长白山哈尔滨——长白山夏季均温22℃,哈尔滨俄式风情拉满&#…

2026/7/1 6:07:25阅读更多 →
如何为小米穿戴设备创建个性化表盘:Mi-Create完整指南与实战教程

如何为小米穿戴设备创建个性化表盘:Mi-Create完整指南与实战教程

如何为小米穿戴设备创建个性化表盘:Mi-Create完整指南与实战教程 【免费下载链接】Mi-Create Unofficial watchface creator for Xiaomi wearables ~2021 and above 项目地址: https://gitcode.com/gh_mirrors/mi/Mi-Create 你是否厌倦了小米手环或智能手表上…

2026/7/1 6:07:25阅读更多 →
别再乱设torch.backends.cudnn了!PyTorch炼丹师必懂的benchmark与deterministic实战避坑指南

别再乱设torch.backends.cudnn了!PyTorch炼丹师必懂的benchmark与deterministic实战避坑指南

PyTorch性能优化与结果复现:深入解析cudnn.benchmark与deterministic的黄金法则在深度学习项目的实际开发中,我们常常面临两个看似矛盾的核心需求:训练速度的最大化和实验结果的完全可复现。这两个需求背后,隐藏着PyTorch框架中两…

2026/7/1 7:13:15阅读更多 →
PromptSRC论文精读:我们是如何让提示学习不再‘过拟合’的?

PromptSRC论文精读:我们是如何让提示学习不再‘过拟合’的?

PromptSRC:如何通过自调节机制突破提示学习的泛化瓶颈当CLIP等视觉语言模型展现出惊人的zero-shot能力时,研究者们很快发现了一个悖论:传统的提示学习方法在提升下游任务表现的同时,往往会以牺牲模型原有的泛化能力为代价。这种现…

2026/7/1 7:13:15阅读更多 →
信创 数据库软件转型

信创 数据库软件转型

数据库软件很多要替换成信创的,所以dba也要跟着转型

2026/7/1 7:13:15阅读更多 →
JMeter分布式压测环境搭建与性能调优实战指南

JMeter分布式压测环境搭建与性能调优实战指南

1. 项目概述:为什么需要分布式压测?做性能测试的朋友,尤其是用过JMeter的,肯定都遇到过单机瓶颈。你兴致勃勃地写好了脚本,模拟了复杂的业务场景,准备大干一场,结果一跑起来,自己的电…

2026/7/1 7:13:15阅读更多 →
告别灾难性遗忘:用PromptSRC让CLIP模型学会新技能,不忘老本行

告别灾难性遗忘:用PromptSRC让CLIP模型学会新技能,不忘老本行

突破灾难性遗忘:PromptSRC如何让CLIP模型实现技能叠加在人工智能领域,视觉语言模型(如CLIP)已经展现出令人惊叹的跨模态理解能力。然而,当工程师们尝试将这些基础模型适配到具体下游任务时,往往会遭遇一个棘…

2026/7/1 7:13:14阅读更多 →
Qt的技巧笔记(一):Qt的QComboBox与自定义的枚举类型的遍历绑定

Qt的技巧笔记(一):Qt的QComboBox与自定义的枚举类型的遍历绑定

步骤1:定义枚举首先,定义你的枚举,通常这会在一个类中完成例如:class MyClass : public QObject {Q_OBJECTpublic:enum MyEnum {Value1,Value2,Value3};Q_ENUM(MyEnum) // 告诉Qt的元对象系统这是一个枚举 };其中,Q_EN…

2026/7/1 7:08:14阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/1 4:42:14阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/1 5:19:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/1 0:01:44阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/1 0:01:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/1 0:01:44阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/1 0:01:44阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/1 0:01:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/1 0:01:44阅读更多 →