一颗平行的心 發表於 2026-1-24 18:12:00

折线图的奇妙变奏:四种创意可视化方法

<p>想象一下折线图就像一条普通的公路,它能带我们从A点到达B点。</p>
<p>但有时我们需要更特别的路线:<strong>环岛</strong>、<strong>盘山公路</strong>、<strong>波浪形赛道</strong>或<strong>螺旋上升</strong>的通道。</p>
<p>在数据可视化中,标准的折线图有时无法充分展示数据的特性,这时我们就需要一些创意变种。</p>
<p>今天将介绍四种特别的折线图变体,它们各有所长,能让你的数据故事更加生动。</p>
<h1 id="1-圆形折线图时间的轮回">1. 圆形折线图:时间的轮回</h1>
<p>如果把普通的折线图首尾相连,放在圆形坐标系中,就得到了圆形折线图。</p>
<p>它特别适合展示<strong>周期性数据</strong>,比如一天24小时的温度变化、一周七天的销售数据,或者一年四季的气候模式。</p>
<p>它的<strong>实现原理</strong>是:使用<strong>极坐标</strong>系统,将角度代表时间或类别,半径代表数值大小。</p>
<p>在<code>matplotlib</code>中,只需要创建一个极坐标子图,然后像普通折线图一样绘制即可。</p>
<pre><code class="language-python"># 圆形折线图
# 数据准备
hours = np.linspace(0, 2 * np.pi, 24, endpoint=False)
values = [] # ....
# 闭合数据
values_cycle = np.concatenate((values, ]))
hours_cycle = np.concatenate((hours, ]))
hour_labels =

fig = plt.figure(figsize=(14, 6))

# --- 左图:普通折线图 ---
ax1 = fig.add_subplot(121)
ax1.plot(range(24), values, marker="o", color="#FF6B6B")
# 省略...

# --- 右图:圆形折线图 ---
ax2 = fig.add_subplot(122, projection="polar")
ax2.plot(hours_cycle, values_cycle, linewidth=2, color="#FF6B6B")
# 省略...

plt.show()
</code></pre>

<p><img src="https://img2024.cnblogs.com/blog/83005/202601/83005-20260124180809921-797291639.png" alt="" loading="lazy"></p>
<p><strong>圆形折线图</strong>在这种场景下的优势在于 <strong>周期性的闭环感</strong>。</p>
<ul>
<li><strong>左图</strong>(普通): 像把这一天的时间切断了,23:00 和 00:00 分隔在两端,看不出它们其实紧挨着。</li>
<li><strong>右图</strong>(圆形): 完美闭合。你能直观地感受到“深夜”是一个连续的时间段。</li>
</ul>
<h1 id="2-斜率图变化的快照">2. 斜率图:变化的快照</h1>
<p>想象一下比较两个人从起点到终点的跑步速度。</p>
<p><strong>斜率图</strong>就像两张快照:一张在起点,一张在终点,中间用直线连接。</p>
<p>线的斜率代表了变化的速率,陡峭的上坡表示大幅增长,平缓的线表示变化不大,下坡则表示下降。</p>
<p>它的<strong>实现原理</strong>:通常在两侧显示两个时间点或两种状态的数据,然后用直线连接对应的数据点。</p>
<p>线的<strong>斜率</strong>直观展示了变化的<strong>大小和方向</strong>。</p>
<pre><code class="language-python"># 斜率图
# 数据
depts = ['销售部', '人事部', '技术部', '研发部', '市场部']
score_before =
score_after =

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))

# --- 左图:普通折线图 ---
x = # 代表前后两个时间点
for i in range(len(depts)):
    ax1.plot(x, , score_after], marker='o', label=depts)
# 省略 ...

# --- 右图:斜率图 ---
for i in range(len(depts)):
    color = 'green' if score_after &gt; score_before else 'red'
    # 绘制线条
    ax2.plot(, , score_after], color=color, marker='o', linewidth=2)
    # 直接在点旁边标注文字,去除图例查找的负担
    ax2.text(-0.05, score_before, f"{depts} {score_before}", ha='right', va='center')
    ax2.text(1.05, score_after, f"{score_after}", ha='left', va='center')

# 省略 ...

plt.tight_layout()
plt.show()
</code></pre>

<p><img src="https://img2024.cnblogs.com/blog/83005/202601/83005-20260124180809903-1147064256.png" alt="" loading="lazy"></p>
<p><strong>斜率图</strong>在这种场景下的优势在于 <strong>极简的变化趋势</strong>。</p>
<ul>
<li><strong>左图</strong>(普通): 虽然也能看,但在坐标轴的干扰下,你需要盯着读数看。</li>
<li><strong>右图</strong>(斜率): 去掉了多余的刻度线,只保留首尾。线条越陡峭,代表变化越剧烈。这就像是从“阅读说明书”变成了“看红绿灯”,一目了然。</li>
</ul>
<h1 id="3-凹凸图排名的舞蹈">3. 凹凸图:排名的舞蹈</h1>
<p>想象一下赛跑中的名次变化:起跑时A领先,中途B反超,最后C冲刺夺冠。</p>
<p><strong>凹凸图</strong>就像记录这场比赛的名次变化表,每个时间点谁在前谁在后一目了然。</p>
<p>它的<strong>实现原理</strong>:通常展示多个项目在不同时间点的排名变化。</p>
<p>每个项目有一条线,线的上下位置代表排名高低。由于排名是相对的,所以这些线总会交叉,形成有趣的波浪形。</p>
<pre><code class="language-python"># 凹凸图
years =
# 排名数据
ranks = {
    '品牌A': ,
    '品牌B': ,
    '品牌C': ,
    '品牌D':
}
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))

# --- 左图:普通折线图 (模拟数值非常接近的情况) ---
# 假设排名对应的数值很接近,很难看清
values_simulated = {
    '品牌A': ,
    '品牌B': ,
    '品牌C': ,
    '品牌D':
}

for brand, val_list in values_simulated.items():
    ax1.plot(years, val_list, marker='o', label=brand)

# 省略 ...

# --- 右图:凹凸图 ---
for idx, (brand, rank_list) in enumerate(ranks.items()):
    ax2.plot(years, rank_list, marker='o', markersize=15, linewidth=4, label=brand, color=colors)
    # 在圆点中写上名次
    for x, y in zip(years, rank_list):
      ax2.text(x, y, str(y), color='white', ha='center', va='center', fontweight='bold')

ax2.invert_yaxis() # 关键:倒转Y轴,让第1名在最上面
# 省略 ...

plt.tight_layout()
plt.show()
</code></pre>

<p><img src="https://img2024.cnblogs.com/blog/83005/202601/83005-20260124180809907-330907440.png" alt="" loading="lazy"></p>
<p><strong>凹凸图</strong>在这种场景下的优势在于 <strong>排名的更替</strong>。</p>
<ul>
<li><strong>左图</strong>(普通): 我们通常画的是“数值”。如果四个品牌的市场份额很接近(比如20%和21%),线条会粘连在一起,很难看清谁第一谁第二。</li>
<li><strong>右图</strong>(凹凸): Y轴不再是数值,而是“名次”。这里将排名均匀拉开,你可以清晰地看到品牌C是如何像黑马一样从最后一名杀到第一名的。</li>
</ul>
<h1 id="4-周期图模式的放大镜">4. 周期图:模式的放大镜</h1>
<p>想象一下观察一年的温度变化。</p>
<p>普通折线图会显示一条有365个点的波浪线,<strong>周期图</strong>则把这365天分成12个月,把每个月的31天叠加在一起比较,就像把一年的温度曲线切成12段,然后并排放在一起。</p>
<p>它的实现原理:将时间序列数据按照周期(天、周、月、年等)切分,然后将每个周期重叠绘制。</p>
<p>这样可以直观比较不同周期内的模式是否相似,以及每个周期相对于整体的表现。</p>
<pre><code class="language-python"># 周期图
months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
# 模拟长数据
sales_2021 =
sales_2022 =
sales_2023 =

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))

# --- 左图:普通折线图 (线性时间轴) ---
# 把所有数据拼成一条长线
all_sales = sales_2021 + sales_2022 + sales_2023
all_months_idx = range(len(all_sales))

ax1.plot(all_months_idx, all_sales, color='#3498db', linewidth=2)
# 省略 ...

# --- 右图:周期图 (叠加时间轴) ---
ax2.plot(months, sales_2021, marker='.', label='2021年', color='lightgrey', linewidth=2, linestyle='--')
ax2.plot(months, sales_2022, marker='.', label='2022年', color='grey', linewidth=2, linestyle='--')
ax2.plot(months, sales_2023, marker='o', label='2023年', color='#3498db', linewidth=3)
# 省略 ...

plt.tight_layout()
plt.show()
</code></pre>

<p><img src="https://img2024.cnblogs.com/blog/83005/202601/83005-20260124180809890-2023106219.png" alt="" loading="lazy"></p>
<p><strong>周期图</strong>在这种场景下的优势在于 <strong>季节性模式的识别</strong>。</p>
<ul>
<li><strong>左图</strong>(普通): 一条长线连绵不断。想要对比2021年7月和2023年7月的数据,眼睛需要在图表左右两端来回横跳,非常累。</li>
<li><strong>右图</strong>(周期): 就像把每年的数据“叠”在了一起。你可以直接看到,无论哪一年,7月都是最高峰,而12月都是低谷。规律一目了然。</li>
</ul>
<h1 id="5-总结">5. 总结</h1>
<p>每种折线图变体都有其独特的价值:</p>
<ul>
<li><strong>圆形折线图</strong>:适合展示周期性数据,首尾相接的设计强调循环</li>
<li><strong>斜率图</strong>:适合比较两个时间点的变化,直观展示变化幅度</li>
<li><strong>凹凸图</strong>:适合展示排名或相对位置的变化,竞争关系一目了然</li>
<li><strong>周期图</strong>:适合比较多个周期的模式,发现季节性规律</li>
</ul>
<p>实际情况下,选择哪种变体取决于你的数据特点和想要传达的信息。</p>
<p><strong>关键</strong>是要记住:可视化不是为了炫技,而是为了更好地讲述数据故事。下次当我们面对数据时,不妨思考一下,哪种"变形"的折线图能让你的故事更加动人。</p>
<p>完整的代码共享在:折线图的4个变种.ipynb (访问密码: 6872)</p><br><br>
来源:https://www.cnblogs.com/wang_yb/p/19527255
頁: [1]
查看完整版本: 折线图的奇妙变奏:四种创意可视化方法