哑铃图:数据对比的优雅之选
<blockquote><p>简洁的线条连接两个数据点,就像哑铃的两端,在对比分析中展现出令人惊艳的清晰度。</p>
</blockquote>
<p>在平时的数据分析项目中,我经常会遇到比较两个相关数据集的变化情况。</p>
<p>这时,传统的做法是使用堆积条形图或簇状条形图,但它们存在一个<strong>共同问题</strong>:当我们需要精确追踪每个项目在两个时间点或两种条件下的变化时,这些图表会让我们的眼睛在条形之间来回跳跃,难以直观把握变化的幅度和方向。</p>
<p>今天,我要向大家推荐一种更优雅的替代方案--<strong>哑铃图</strong>。</p>
<h1 id="1-哑铃图是什么">1. 哑铃图是什么?</h1>
<p><strong>哑铃图</strong>(<code>Dumbbell Plot</code>),有时也称为<strong>DNA图</strong>或<strong>杠铃图</strong>,是一种用于比较两个相关数据点的可视化图表。</p>
<p>它源于人们对更有效数据比较方式的持续探索。</p>
<p>在传统的时间序列比较中,我们通常使用两条折线,但当需要比较的项目较多时,折线图会变得混乱。<strong>哑铃图</strong>通过将比较焦点放在每个项目的两个状态上,解决了多项目对比时的视觉混乱问题。</p>
<p>它的<strong>基本结构</strong>很简单:</p>
<ul>
<li>每个观察单位(如产品、地区、时间段)对应两个数据点</li>
<li>这两个数据点由一条直线(或线段)连接</li>
<li>整个图形看起来像一排排哑铃,因而得名</li>
</ul>
<h1 id="2-实现原理">2. 实现原理</h1>
<p><strong>哑铃图</strong>的核心设计理念是<strong>最小化认知负荷</strong>。</p>
<p>当我们需要比较A和B时,最直接的方式就是把它们放在一起,用一条线连接,然后观察这条线的长度(差异大小)和方向(哪个更大)。</p>
<p>在<code>matplotlib</code>中创建<strong>哑铃图</strong>,我们主要使用以下元素:</p>
<ul>
<li><strong>散点图</strong>:表示两个数据点</li>
<li><strong>直线段</strong>:连接两个相关点</li>
<li><strong>颜色编码</strong>:通常用不同颜色区分前后状态或不同组别</li>
<li><strong>标签系统</strong>:清晰标识每个观察单位</li>
</ul>
<h1 id="3-实战示例">3. 实战示例</h1>
<p>接下来,我们看看哑铃图在实际场景中的显示效果。</p>
<p>假设我们是一家电商公司的数据分析师,需要比较8个主要产品类别在2022年和2023年的销售额变化。</p>
<p>(完整的代码在文章末尾提供下载地址,文中只截取部分代码)</p>
<p>先创建一些测试数据:</p>
<pre><code class="language-python"># 示例数据:8个产品类别在2022年和2023年的销售额(单位:万元)
categories = [
"电子产品",
"服装鞋帽",
"家居用品",
"美妆护肤",
"图书音像",
"运动户外",
"食品饮料",
"母婴用品",
]
sales_2022 =
sales_2023 =
</code></pre>
<p>然后,我们绘制传统的簇状条形图和哑铃图来对比一下效果:</p>
<pre><code class="language-python"># 创建子图,对比两种可视化方法
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 8))
# 簇状条形图
x = np.arange(len(categories))
bars1 = ax1.bar(x - width/2, sales_2022, width, label='2022年', color='#4C72B0', alpha=0.8)
bars2 = ax1.bar(x + width/2, sales_2023, width, label='2023年', color='#DD8452', alpha=0.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(, , color=line_color, linewidth=2.5, alpha=0.7, zorder=1)
# 绘制数据点
ax2.scatter(sales_2022, y_pos, s=120, color='#4C72B0', alpha=0.9, label='2022年', zorder=2, edgecolors='white', linewidth=2)
ax2.scatter(sales_2023, y_pos, s=120, color='#DD8452', alpha=0.9, label='2023年', zorder=2, edgecolors='white', linewidth=2)
# 省略 ...
plt.tight_layout()
plt.show()
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202601/83005-20260122232220614-1554024714.png" alt="" loading="lazy"></p>
<p>通过上面的对比,我们可以清晰地看到<strong>哑铃图</strong>的优势:</p>
<ul>
<li><strong>变化一目了然</strong>:连接线的长度直观表示变化幅度,方向表示增长或下降</li>
<li><strong>减少视觉跳跃</strong>:眼睛不需要在条形间来回移动,而是沿着水平线自然追踪</li>
<li><strong>突出比较重点</strong>:专注于每个项目的两个状态对比,而非绝对数值</li>
</ul>
<p>进一步,我们还可以给<strong>哑铃图</strong>排序,按照增长<strong>由快到慢</strong>给各个品类排序,这样自然形成从"下降最显著"到"增长最显著"的连续谱,模式自动显现,无需刻意寻找。</p>
<p>比如上面的<strong>哑铃图</strong>中,【服装鞋帽】这个品类其实销售额是下降的,混在一堆哑铃中不容易看出来吧?</p>
<pre><code class="language-python"># 创建排序后的哑铃图
fig, ax = plt.subplots(figsize=(10, 8))
# 按变化幅度排序
sorted_indices = np.argsort(
- sales_2022 for i in range(len(categories))]
)
sorted_categories = for i in sorted_indices]
sorted_2022 = for i in sorted_indices]
sorted_2023 = for i in sorted_indices]
# 绘制连接线
# 省略 ...
# 绘制数据点
# 省略 ...
# 添加变化箭头标注
# 省略 ...
plt.tight_layout()
plt.show()
</code></pre>
<p><img src="https://img2024.cnblogs.com/blog/83005/202601/83005-20260122232220694-18227431.png" alt="" loading="lazy"></p>
<p>这样改造后,由上到下的哑铃,越来越短(也就是增长越来越慢),最底部的那个是<strong>负增长</strong>,用了<strong>红色</strong>来标注。</p>
<h1 id="4-总结">4. 总结</h1>
<p>数据可视化的核心目标是<strong>有效传达信息</strong>。当我们需要强调变化、比较两个相关状态时,<strong>哑铃图</strong>提供了一种简洁而强大的解决方案。</p>
<p>就像选择合适的工具完成工作一样,在面对数据比较任务时,我们应该根据具体需求选择最合适的可视化形式:</p>
<ul>
<li>当需要比较多个项目的两个状态时,选择<strong>哑铃图</strong></li>
<li>当需要展示单个项目的多个组成部分时,选择<strong>堆积条形图</strong></li>
<li>当需要比较多个项目的多个类别时,选择<strong>簇状条形图</strong></li>
</ul>
<p>最好的可视化不是最复杂的,而是能让观众在最短时间内理解最多信息的那个。</p>
<p><strong>哑铃图</strong>正是这样一种高效的工具,它用最简单的线条连接,讲述了数据世界中最动人的变化故事。</p>
<p>下次做报告时,不妨试着把那张拥挤的簇状条形图换成<strong>哑铃图</strong>,相信你的观众会感叹:“哇,这张图做得真专业!”</p>
<p>完整代码:哑铃图.ipynb (访问密码: 6872)</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/19519312
頁:
[1]