博客 / 詳情

返回

折線圖的奇妙變奏:四種創意可視化方法

想象一下折線圖就像一條普通的公路,它能帶我們從A點到達B點。

但有時我們需要更特別的路線:環島盤山公路波浪形賽道螺旋上升的通道。

在數據可視化中,標準的折線圖有時無法充分展示數據的特性,這時我們就需要一些創意變種。

今天將介紹四種特別的折線圖變體,它們各有所長,能讓你的數據故事更加生動。

1. 圓形折線圖:時間的輪迴

如果把普通的折線圖首尾相連,放在圓形座標系中,就得到了圓形折線圖。

它特別適合展示週期性數據,比如一天24小時的温度變化、一週七天的銷售數據,或者一年四季的氣候模式。

它的實現原理是:使用極座標系統,將角度代表時間或類別,半徑代表數值大小。

matplotlib中,只需要創建一個極座標子圖,然後像普通折線圖一樣繪製即可。

# 圓形折線圖
# 數據準備
hours = np.linspace(0, 2 * np.pi, 24, endpoint=False)
values = [] # ....
# 閉合數據
values_cycle = np.concatenate((values, [values[0]]))
hours_cycle = np.concatenate((hours, [hours[0]]))
hour_labels = [f"{h}點" for h in range(24)]

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()

圓形折線圖在這種場景下的優勢在於 週期性的閉環感

  • 左圖(普通): 像把這一天的時間切斷了,23:00 和 00:00 分隔在兩端,看不出它們其實緊挨着。
  • 右圖(圓形): 完美閉合。你能直觀地感受到“深夜”是一個連續的時間段。

2. 斜率圖:變化的快照

想象一下比較兩個人從起點到終點的跑步速度。

斜率圖就像兩張快照:一張在起點,一張在終點,中間用直線連接。

線的斜率代表了變化的速率,陡峭的上坡表示大幅增長,平緩的線表示變化不大,下坡則表示下降。

它的實現原理:通常在兩側顯示兩個時間點或兩種狀態的數據,然後用直線連接對應的數據點。

線的斜率直觀展示了變化的大小和方向

# 斜率圖
# 數據
depts = ['銷售部', '人事部', '技術部', '研發部', '市場部']
score_before = [65, 70, 88, 85, 60]
score_after = [85, 68, 92, 80, 90]

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

# --- 左圖:普通折線圖 ---
x = [1, 2] # 代表前後兩個時間點
for i in range(len(depts)):
    ax1.plot(x, [score_before[i], score_after[i]], marker='o', label=depts[i])
# 省略 ...

# --- 右圖:斜率圖 ---
for i in range(len(depts)):
    color = 'green' if score_after[i] > score_before[i] else 'red'
    # 繪製線條
    ax2.plot([0, 1], [score_before[i], score_after[i]], color=color, marker='o', linewidth=2)
    # 直接在點旁邊標註文字,去除圖例查找的負擔
    ax2.text(-0.05, score_before[i], f"{depts[i]} {score_before[i]}", ha='right', va='center')
    ax2.text(1.05, score_after[i], f"{score_after[i]}", ha='left', va='center')

# 省略 ...

plt.tight_layout()
plt.show()

斜率圖在這種場景下的優勢在於 極簡的變化趨勢

  • 左圖(普通): 雖然也能看,但在座標軸的干擾下,你需要盯着讀數看。
  • 右圖(斜率): 去掉了多餘的刻度線,只保留首尾。線條越陡峭,代表變化越劇烈。這就像是從“閲讀説明書”變成了“看紅綠燈”,一目瞭然。

3. 凹凸圖:排名的舞蹈

想象一下賽跑中的名次變化:起跑時A領先,中途B反超,最後C衝刺奪冠。

凹凸圖就像記錄這場比賽的名次變化表,每個時間點誰在前誰在後一目瞭然。

它的實現原理:通常展示多個項目在不同時間點的排名變化。

每個項目有一條線,線的上下位置代表排名高低。由於排名是相對的,所以這些線總會交叉,形成有趣的波浪形。

# 凹凸圖
years = [2019, 2020, 2021, 2022, 2023]
# 排名數據
ranks = {
    '品牌A': [1, 1, 2, 3, 4],
    '品牌B': [4, 3, 1, 1, 2],
    '品牌C': [2, 4, 3, 2, 1],
    '品牌D': [3, 2, 4, 4, 3]
}
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']

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

# --- 左圖:普通折線圖 (模擬數值非常接近的情況) ---
# 假設排名對應的數值很接近,很難看清
values_simulated = {
    '品牌A': [30, 31, 25, 20, 15],
    '品牌B': [10, 15, 30, 32, 28],
    '品牌C': [25, 12, 22, 28, 35],
    '品牌D': [20, 22, 18, 15, 20]
}

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[idx])
    # 在圓點中寫上名次
    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()

凹凸圖在這種場景下的優勢在於 排名的更替

  • 左圖(普通): 我們通常畫的是“數值”。如果四個品牌的市場份額很接近(比如20%和21%),線條會粘連在一起,很難看清誰第一誰第二。
  • 右圖(凹凸): Y軸不再是數值,而是“名次”。這裏將排名均勻拉開,你可以清晰地看到品牌C是如何像黑馬一樣從最後一名殺到第一名的。

4. 週期圖:模式的放大鏡

想象一下觀察一年的温度變化。

普通折線圖會顯示一條有365個點的波浪線,週期圖則把這365天分成12個月,把每個月的31天疊加在一起比較,就像把一年的温度曲線切成12段,然後並排放在一起。

它的實現原理:將時間序列數據按照週期(天、周、月、年等)切分,然後將每個週期重疊繪製。

這樣可以直觀比較不同週期內的模式是否相似,以及每個週期相對於整體的表現。

# 週期圖
months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
# 模擬長數據
sales_2021 = [20, 25, 35, 50, 80, 100, 110, 105, 70, 50, 30, 25]
sales_2022 = [22, 28, 40, 55, 85, 105, 115, 100, 75, 55, 35, 28]
sales_2023 = [25, 30, 45, 60, 95, 120, 130, 115, 80, 60, 40, 35]

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()

週期圖在這種場景下的優勢在於 季節性模式的識別

  • 左圖(普通): 一條長線連綿不斷。想要對比2021年7月和2023年7月的數據,眼睛需要在圖表左右兩端來回橫跳,非常累。
  • 右圖(週期): 就像把每年的數據“疊”在了一起。你可以直接看到,無論哪一年,7月都是最高峯,而12月都是低谷。規律一目瞭然。

5. 總結

每種折線圖變體都有其獨特的價值:

  • 圓形折線圖:適合展示週期性數據,首尾相接的設計強調循環
  • 斜率圖:適合比較兩個時間點的變化,直觀展示變化幅度
  • 凹凸圖:適合展示排名或相對位置的變化,競爭關係一目瞭然
  • 週期圖:適合比較多個週期的模式,發現季節性規律

實際情況下,選擇哪種變體取決於你的數據特點和想要傳達的信息。

關鍵是要記住:可視化不是為了炫技,而是為了更好地講述數據故事。下次當我們面對數據時,不妨思考一下,哪種"變形"的折線圖能讓你的故事更加動人。

完整的代碼共享在:折線圖的4個變種.ipynb (訪問密碼: 6872)

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.