【matplotlib 實戰】--平行坐標系

来源:https://www.cnblogs.com/wang_yb/archive/2023/10/04/17742169.html
-Advertisement-
Play Games

平行坐標系是一種統計圖表,它包含多個垂直平行的坐標軸,每個軸表示一個欄位,並用刻度標明範圍。通過在每個軸上找到數據點的落點,並將它們連接起來形成折線,可以很容易地展示多維數據。隨著數據增多,折線會堆疊,分析者可以從中發現數據的特性和規律,比如發現數據之間的聚類關係。 儘管平行坐標系與折線圖錶面上看起 ...


平行坐標系是一種統計圖表,它包含多個垂直平行的坐標軸,每個軸表示一個欄位,並用刻度標明範圍。通過在每個軸上找到數據點的落點,並將它們連接起來形成折線,可以很容易地展示多維數據。
隨著數據增多,折線會堆疊,分析者可以從中發現數據的特性和規律,比如發現數據之間的聚類關係。

儘管平行坐標系與折線圖錶面上看起來相似,但它並不表示趨勢,各個坐標軸之間也沒有因果關係。
因此,在使用平行坐標系時,軸的順序是可以人為決定的,這會影響閱讀的感知和判斷。較近的兩根坐標軸會使對比感知更強烈。
因此,為了得出最合適和美觀的排序方式,通常需要進行多次試驗和比較。

同時,嘗試不同的排序方式也可能有助於得出更多的結論。

此外,平行坐標系的每個坐標軸很可能具有不同的數據範圍,這容易導致讀者的誤解。
因此,在繪製圖表時,最好明確標明每個軸上的最小值和最大值。

1. 主要元素

平行坐標系是一種常用的數據可視化方法,用於展示多個維度的數據,並通過連接這些維度的線段來揭示它們之間的關係。

它的主要元素包括:

  1. 坐標軸:平行坐標系通常由垂直於數據維度的坐標軸組成,每個坐標軸代表一個數據維度。
  2. 數據點:每個數據點在平行坐標系中由一條連接各個坐標軸的線段表示,線段的位置和形狀反映了數據點在各個維度上的取值。
  3. 連接線:連接線用於將同一數據點在不同維度上的線段連接起來,形成數據點的輪廓,幫助觀察者理解數據點在各個維度上的變化趨勢。

image.png

2. 適用的場景

平行坐標系適用的場景有:

  • 多維數據分析:平行坐標系適用於展示多個維度的數據,幫助觀察者發現不同維度之間的關係和趨勢,例如在探索數據集中的模式、異常值或相關性時。
  • 數據分類和聚類:通過觀察數據點的輪廓和分佈,可以幫助觀察者識別不同的數據類別或聚類。
  • 數據交互與過濾:平行坐標系可以支持互動式數據探索和過濾,通過選擇或操作特定的坐標軸或線段,可以對數據進行篩選和聚焦。

3. 不適用的場景

平行坐標系不適用的場景有:

  • 數據維度過多:當數據維度過多時,平行坐標系的可讀性和解釋性可能會下降,因為線段之間的交叉和重疊會導致視覺混亂。
  • 數據維度之間差異較大:如果數據在不同維度上的取值範圍差異較大,那麼線段之間的比較和分析可能會受到影響,因為較小的取值範圍可能會被較大的取值範圍所掩蓋。
  • 數據具有時間序列:平行坐標系並不適用於展示時間序列數據,因為它無法準確地表示數據的時間順序。在這種情況下,其他的數據可視化方法,如折線圖或時間軸圖,可能更適合。

4. 分析實戰

平行坐標系適用於展示具有相同屬性的一系列數據,每個坐標系代表一種屬性。
這次選用了國家統計局公開的教育類數據:https://databook.top/nation/A0M

選取其中幾類具有相同屬性的數據:

  1. A0M06:各級各類學校專任教師數
  2. A0M07:各級各類學校招生數
  3. A0M08:各級各類學校在校學生數
  4. A0M09:各級各類學校畢業生數

4.1. 數據來源

四個原始數據集是按照年份統計的:

fp = "d:/share/A0M06.csv"

df = pd.read_csv(fp)
df

image.png

這是教師相關統計數據,其他3個數據集的結構也類似。

4.2. 數據清理

平行坐標系比較的是屬性,不需要每年的數據。
所以,對於上面4個數據集,分別提取2022年小學初中高中特殊教育相關4個屬性的數據。

import os

files = {
    "教師數": "A0M06.csv",
    "招生數": "A0M07.csv",
    "在校學生數": "A0M08.csv",
    "畢業學生數": "A0M09.csv",
}
data_dir = "d:/share"

data = pd.DataFrame()
for key in files:
    fp = os.path.join(data_dir, files[key])
    df = pd.read_csv(fp)
    df_filter = pd.DataFrame(
        [[
            key,
            df.loc[225, "value"],
            df.loc[135, "value"],
            df.loc[90, "value"],
            df.loc[270, "value"],
        ]],
        columns=["name", "小學", "初中", "高中", "特殊教育"],
    )
    data = pd.concat([data, df_filter])

data

image.png

4.3. 分析結果可視化

平行坐標系在 matplotlib 中沒有直接提供,實現起來也不難:

import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches
import numpy as np

xnames = data.loc[:, "name"]
ynames = ["小學", "初中", "高中", "特殊教育"]
ys = np.array(data.iloc[:, 1:].values.tolist())
ymins = ys.min(axis=0)
ymaxs = ys.max(axis=0)
dys = ymaxs - ymins
ymins -= dys * 0.05  # Y軸的上下限增加 5% 的冗餘
ymaxs += dys * 0.05

#每個坐標系的上下限不一樣,調整顯示方式
zs = np.zeros_like(ys)
zs[:, 0] = ys[:, 0]
zs[:, 1:] = (ys[:, 1:] - ymins[1:]) / dys[1:] * dys[0] + ymins[0]

fig, host = plt.subplots(figsize=(10, 4))

axes = [host] + [host.twinx() for i in range(ys.shape[1] - 1)]
for i, ax in enumerate(axes):
    ax.set_ylim(ymins[i], ymaxs[i])
    ax.spines["top"].set_visible(False)
    ax.spines["bottom"].set_visible(False)
    if ax != host:
        ax.spines["left"].set_visible(False)
        ax.yaxis.set_ticks_position("right")
        ax.spines["right"].set_position(("axes", i / (ys.shape[1] - 1)))

host.set_xlim(0, ys.shape[1] - 1)
host.set_xticks(range(ys.shape[1]))
host.set_xticklabels(ynames, fontsize=14)
host.tick_params(axis="x", which="major", pad=7)
host.spines["right"].set_visible(False)
host.xaxis.tick_top()
host.set_title("各類學校的師生數目比較", fontsize=18, pad=12)

colors = plt.cm.Set1.colors
legend_handles = [None for _ in xnames]
for j in range(ys.shape[0]):
    verts = list(
        zip(
            [x for x in np.linspace(0, len(ys) - 1, len(ys) * 3 - 2, endpoint=True)],
            np.repeat(zs[j, :], 3)[1:-1],
        )
    )
    codes = [Path.MOVETO] + [Path.CURVE4 for _ in range(len(verts) - 1)]
    path = Path(verts, codes)
    patch = patches.PathPatch(
        path, facecolor="none", lw=2, alpha=0.7, edgecolor=colors[j]
    )
    legend_handles[j] = patch
    host.add_patch(patch)

host.legend(
    xnames,
    loc="lower center",
    bbox_to_anchor=(0.5, -0.18),
    ncol=len(xnames),
    fancybox=True,
    shadow=True,
)
plt.tight_layout()
plt.show()

image.png

從圖表中,可以看出一下幾點,和我們對實際情況的印象是差不多的:

  1. 教師數量遠小於學生數量
  2. 從小學到初中,高中,學生數量不斷減少
  3. 招生數量和畢業生數量差不多

平行坐標系用於比較不同數據集相同屬性


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 【中秋國慶不斷更】OpenHarmony組件內狀態變數使用:@State裝飾器 @State裝飾的變數,或稱為狀態變數,一旦變數擁有了狀態屬性,就和自定義組件的渲染綁定起來。當狀態改變時,UI會發生對應的渲染改變。 在狀態變數相關裝飾器中,@State是最基礎的,使變數擁有狀態屬性的裝飾器,它也是大 ...
  • 【中秋國慶不斷更】HarmonyOS對通知類消息的管理與發佈通知(下) 一、發佈進度條類型通知 進度條通知也是常見的通知類型,主要應用於文件下載、事務處理進度顯示。HarmonyOS提供了進度條模板,發佈通知應用設置好進度條模板的屬性值,如模板名、模板數據,通過通知子系統發送到通知欄顯示。 目前系統 ...
  • Python中的變數 變數的定義 程式中,數據都臨時存儲在記憶體中。每一個被存儲在記憶體的數據都有一個記憶體地址。其中特定的數據被我們所使用,因此我們為那些記憶體地址定義了名稱。這一名稱被稱作 標識符,又稱變數名。而與變數名對應記憶體地址中的數據被稱為變數值。 總結:變數為記憶體中特定的數據。它的記憶體地址的名稱 ...
  • 在這,您將學習瞭解 Spring Boot Starter Parent, 它是 Spring Boot 提供的父級 Pom 文件,旨在提供自動版本依賴管理,幫助我們輕鬆快速地進行 Spring Boot 開發。 什麼是 Spring Boot Starter Parent ? 通過 Spring ...
  • 用Rust手把手編寫一個wmproxy(代理,內網穿透等), HTTP及TCP內網穿透原理及運行篇 項目 ++wmproxy++ gite: https://gitee.com/tickbh/wmproxy github: https://github.com/tickbh/wmproxy 內網、公 ...
  • Dart 3.0在語法層面共發佈了3個高級特性,第一個特性Record記錄我們在前面已經學習和探究。今天我們來學習第二個高級類型Pattern模式,由於內容較多,共分2篇文章進行介紹,本文首先介紹模式的概覽和用法,包括匹配、解構、在變數申明、賦值、迴圈、表達式等應用場景…… ...
  • 背包問題-01背包 首先我們要明白什麼是01背包,在下述例題中,由於每個物體只有兩種可能的狀態(取與不取),對應二進位中的 \(0\) 和 \(1\),這類問題便被稱為\(\text{「0-1 背包問題」}\)。 題目描述 有 \(N\) 件物品和一個容量為 \(M\) 的背包。第 \(i\) 件物 ...
  • 1.JVM體繫結構 JVM的位置 JVM體繫結構 2.類載入器 雙親委派機制 package java.lang; /** * 測試自定義java.lang.String類能否運行成功 * 體會雙親委派機制 * * 類載入器逐級向上檢查:app->ext->boot * 發現boot類載入器中也有S ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...