MATLAB 山脊圖繪制全解析:從數據生成到可視化進階

一、引言:當數據分布擁有「層次感」—— 山脊圖的魅力?

在數據可視化的世界里,我們常常需要同時展示多個分布的形態差異。傳統的重疊密度圖雖然能呈現整體趨勢,但當分布數量較多時,曲線交疊會讓畫面變得雜亂。這時候,山脊圖(Ridgeline Plot)就像一位優雅的舞者,用層次分明的「數據山脈」展現每個分布的獨特輪廓,讓復雜數據瞬間變得清晰易懂。?

今天,我們將通過一段完整的 MATLAB 代碼,帶大家從零開始實現一個精美的山脊圖。不僅會詳細解析每一行代碼的作用,還會告訴你如何替換成自己的數據,甚至玩轉可視化細節優化。準備好了嗎?讓我們一起走進這場「數據山脈」的繪制之旅吧!🌄?

二、代碼全景:先睹為快的完整實現?

在正式解析前,先放上完整的 MATLAB 代碼,方便大家有一個整體認知:

% 生成山脊圖數據并繪圖
rng(42); % 設置隨機種子保證可重復性% 參數設置
numSamples = 10;   % 樣本數 (A-J)
numPoints = 500;   % 每個樣本的數據點數
x = linspace(0, 90, numPoints); % X軸范圍0-90
yOffset = 1.5;     % 樣本間的垂直間距% 生成隨機均值和標準差 (控制分布位置和寬度)
mus = linspace(20, 70, numSamples);
sigmas = linspace(4, 12, numSamples) .* rand(1, numSamples);% 預計算核密度并繪圖
figure('Color', 'white');
hold on;% 顏色映射 (從藍到紅)
colors = parula(numSamples);for i = numSamples:-1:1  % 倒序繪制確保標簽位置正確% 生成正態分布隨機數據data = mus(i) + sigmas(i) * randn(numPoints, 1);% 計算核密度估計[f, xi] = ksdensity(data, x, 'Bandwidth', 3);f_normalized = f / max(f) * 0.8; % 歸一化高度% 計算當前樣本的基線baseline = (numSamples - i) * yOffset;% 繪制填充區域fill([xi, fliplr(xi)], ...[baseline + f_normalized, fliplr(baseline*ones(1, numPoints))], ...colors(i, :), ...'FaceAlpha', 0.7, ...'EdgeColor', 'none');% 添加樣本標簽text(5, baseline + 0.3, ['Sample ', char('A' + numSamples - i)], ...'FontWeight', 'bold', ...'FontSize', 10);
end% 美化圖形
set(gca, 'YTick', [], 'YColor', 'none'); % 隱藏Y軸
xlabel('K (w)');
title('Ridgeline Plot', 'FontSize', 14);
grid on;
box on;
xlim([0, 90]);
ylim([0, yOffset*numSamples + 0.5]);
hold off;

運行這段代碼,你會得到一個包含 10 個樣本分布的山脊圖,每個「山脊」代表一個樣本的密度分布,垂直排列的設計讓每個分布的位置、寬度和峰值一目了然。接下來,我們逐行拆解其中的關鍵邏輯。?

三、核心代碼解析:數據生成與可視化的「山脈構造」?

1. 隨機種子設置:讓結果可復現的「魔法咒語」

rng(42); % 設置隨機種子保證可重復性
  • 作用:rng函數用于設置隨機數生成器的種子,這里使用42作為種子(一個在編程界充滿神秘色彩的數字😉)。設置后,每次運行代碼生成的隨機數序列都相同,確保結果可復現,這對學術研究或協作場景非常重要。?
  • 可替換點:如果不需要固定隨機結果,直接刪除這行即可;若想換一個固定結果,修改括號內的數字(如rng(123))。?

2. 參數設置:定義「山脈」的基本框架

numSamples = 10;   % 樣本數 (A-J)
numPoints = 500;   % 每個樣本的數據點數
x = linspace(0, 90, numSamples); % X軸范圍0-90
yOffset = 1.5;     % 樣本間的垂直間距
  • numSamples:控制樣本數量,代碼中生成了 A-J 共 10 個樣本,對應 10 個「山脊」。如果你有 20 個樣本,這里就設為 20。?
  • numPoints:每個樣本生成的數據點數,數值越大,密度曲線越平滑(但計算量也會增加),通常 500-1000 是不錯的選擇。?
  • x:定義 X 軸的范圍和采樣點,這里用linspace(0, 90, 500)生成從 0 到 90 均勻分布的 500 個點,作為密度估計的橫軸坐標。?
  • yOffset:控制每個樣本在 Y 軸方向的間距,數值越大,「山脊」之間的間隔越寬,避免重疊過多;數值越小,畫面更緊湊。?

3. 分布參數生成:賦予每個「山脊」獨特形態

mus = linspace(20, 70, numSamples);
sigmas = linspace(4, 12, numSamples) .* rand(1, numSamples);
  • 均值mus:使用linspace生成從 20 到 70 的等差數列,作為每個樣本正態分布的均值。這樣樣本的中心位置會從左到右逐漸移動,形成明顯的位置差異。?
  • 標準差sigmas:基礎范圍是 4 到 12,再乘以一個隨機數(rand(1, numSamples)生成 0-1 之間的隨機數),讓每個樣本的分布寬度既有規律又有變化。這樣有的「山脊」瘦高(標準差小),有的矮胖(標準差大),模擬真實數據的多樣性。?

4. 圖形初始化與顏色映射:搭建畫布與調色盤

figure('Color', 'white'); % 創建白色背景的畫布
hold on; % 保持圖形,允許后續添加元素
colors = parula(numSamples); % 生成與樣本數匹配的顏色映射(Parula色階,MATLAB默認的優秀色階)
  • 畫布設置:figure('Color', 'white')創建一個白色背景的圖形窗口,避免默認灰色背景干擾數據展示。?
  • 顏色映射:parula是 MATLAB 推薦的感知均勻色階,適合連續數據可視化。numSamples決定顏色數量,每個樣本對應一種顏色,這里從藍到紅漸變,視覺上容易區分。?

5. 循環繪制:逐個構建「山脊」的核心邏輯

for i = numSamples:-1:1  % 倒序繪制確保標簽位置正確

這里使用倒序循環(從 10 到 1),是因為后續繪制時,底層的「山脊」會被上層覆蓋,倒序可以先畫底層樣本,再畫上層,避免標簽被遮擋(后面會詳細解釋標簽位置)。?

5.1 生成正態分布數據

data = mus(i) + sigmas(i) * randn(numPoints, 1);
  • 利用正態分布公式均值 + 標準差×隨機數生成數據,randn生成服從標準正態分布的隨機數,numPoints, 1表示生成 500 行 1 列的列向量。?

5.2 核密度估計:讓離散數據「平滑成山」

[f, xi] = ksdensity(data, x, 'Bandwidth', 3);
  • ksdensity函數:用于計算核密度估計(Kernel Density Estimation, KDE),將離散數據轉換為連續的密度曲線。?
  • data:輸入的樣本數據(列向量)。?
  • x:指定計算密度的橫軸坐標(即前面定義的 0-90 的 500 個點)。?
  • 'Bandwidth':帶寬參數,控制曲線平滑度。數值越大,曲線越平滑;越小,越貼近原始數據波動。這里設為 3,是一個平衡值。?
  • 輸出f是密度估計值,xi是對應的橫軸坐標(與x相同,這里主要是為了代碼一致性)。?

5.3 歸一化處理:控制「山脊」高度

f_normalized = f / max(f) * 0.8; % 歸一化高度
  • 為什么歸一化?直接使用密度值繪制會導致不同樣本的「山脊」高度差異過大(因為密度值與數據范圍相關),歸一化后將每個樣本的密度峰值縮放到 0.8 倍的相對高度,讓所有「山脊」在視覺上高度統一,便于比較形狀而非絕對密度。?

5.4 基線計算:確定「山脊」的垂直位置

baseline = (numSamples - i) * yOffset;
  • 第一個樣本(i=10)的基線是(10-10)*1.5=0,第二個(i=9)是(10-9)*1.5=1.5,依此類推,最后一個樣本(i=1)是(10-1)*1.5=13.5。這樣每個樣本從上到下依次排列,間距為 1.5。?

5.5 繪制填充區域:用顏色填充「山體」

fill([xi, fliplr(xi)], ...[baseline + f_normalized, fliplr(baseline*ones(1, numPoints))], ...colors(i, :), ...'FaceAlpha', 0.7, ...'EdgeColor', 'none');
  • 填充原理:fill函數通過指定頂點坐標繪制多邊形。這里將密度曲線的點(xi, baseline + f_normalized)與基線的反向點(fliplr(xi), baseline)連接,形成一個閉合區域(類似梯形 + 曲線的形狀)。?
  • fliplr(xi):將 xi 反轉,用于閉合路徑的底部橫軸。?
  • baseline*ones(1, numPoints):生成與 xi 等長的基線向量,反轉后作為底部 Y 坐標,形成從曲線到基線的閉合區域。?
  • 視覺參數:?
  • FaceAlpha=0.7:設置填充顏色透明度,避免完全不透明導致下層「山脊」被遮擋。?
  • EdgeColor='none':不繪制邊框,讓圖形更簡潔。?

5.6 添加樣本標簽:給每座「山」命名

text(5, baseline + 0.3, ['Sample ', char('A' + numSamples - i)], ...'FontWeight', 'bold', ...'FontSize', 10);
  • 標簽邏輯:利用倒序循環,當 i=10 時,numSamples - i=0,標簽為 'A';i=9 時,numSamples - i=1,標簽為 'B',依此類推,最終生成 A-J 的標簽。?
  • 位置設置:X 坐標固定為 5(位于畫布左側),Y 坐標為基線 + 0.3,確保標簽顯示在對應「山脊」的左側空白處,不與圖形重疊。?

四、用戶數據替換指南:讓代碼適配你的場景?

現在重點來了!如果你想將這段代碼用于自己的數據,需要修改哪些部分呢?以下是詳細的替換指南:?

1. 替換原始數據:從隨機生成到真實輸入?

當前代碼使用正態分布隨機數據,如果你有真實數據,步驟如下:?

場景一:已知每個樣本的原始數據?

  • 數據格式:假設你有 10 個樣本,每個樣本的數據存儲為單元格數組data_samples,其中data_samples{1}是樣本 A 的數據,data_samples{2}是樣本 B 的數據,依此類推。?
  • 修改代碼:?
  • 刪除mus和sigmas的生成代碼。?
  • 在循環中,將data = mus(i) + sigmas(i) * randn(...)替換為data = data_samples{i};。?
  • 確保每個樣本的數據點數可以不同(但ksdensity會自動處理,無需統一長度)。?

場景二:已知每個樣本的均值和標準差?

  • 如果你只有均值和標準差(比如通過統計得到),直接替換mus和sigmas為你的數據:
mus = [25, 30, 35, 40, 45, 50, 55, 60, 65, 70]; % 自定義均值
sigmas = [5, 6, 7, 8, 9, 10, 9, 8, 7, 6]; % 自定義標準差

2. 修改 X 軸范圍和標簽?

  • 當前 X 軸標簽是 'K (w)',如果你是其他數據(如溫度、時間、分數),直接修改xlabel內容:
xlabel('溫度 (℃)'); % 示例:溫度數據

X 軸范圍x = linspace(0, 90, numPoints)可根據數據實際范圍調整,比如數據在 10-80 之間,改為:?

x = linspace(10, 80, 500);

3. 調整樣本數量和間距?

  • 增加 / 減少樣本數:修改numSamples,比如設為 15,同時確保你的數據有 15 個樣本。?
  • 調整垂直間距:修改yOffset,數值越大,「山脊」之間越稀疏(建議 0.5-2 之間調整,根據樣本數量選擇:樣本多則間距小,樣本少可適當增大)。?

4. 自定義顏色和標簽?

  • 顏色映射:默認使用parula色階,可替換為其他色階(如jet、hot、cool),或自定義顏色矩陣:
colors = [0 0 1; 0 0.5 1; 0 1 1; ...]; % 自定義RGB顏色,每行一個顏色

標簽內容:當前標簽是 'Sample A-J',可替換為自定義標簽,比如樣本名稱數組:?

labels = {'Group 1', 'Group 2', 'Group 3', ..., 'Group 10'}; % 定義標簽數組
text(5, baseline + 0.3, labels{numSamples - i + 1}, ...); % 注意索引順序

五、細節優化:讓圖形更專業美觀?

1. 坐標軸與網格設置

set(gca, 'YTick', [], 'YColor', 'none'); % 隱藏Y軸
grid on; % 顯示網格線
box on; % 顯示圖形邊框
xlim([0, 90]); % 固定X軸范圍
ylim([0, yOffset*numSamples + 0.5]); % 自動計算Y軸范圍
  • 隱藏 Y 軸:山脊圖的 Y 軸通常不代表實際數據,只是垂直間距,所以隱藏 Y 軸刻度和標簽,讓焦點集中在 X 軸和分布形態上。?
  • 網格與邊框:網格線幫助觀察 X 軸數值,邊框讓圖形更規整。?

2. 標題與字體設置

title('Ridgeline Plot', 'FontSize', 14); % 主標題
% 可添加副標題:
text(0.5, 1.05, '多個樣本分布對比', 'FontSize', 12, 'FontWeight', 'bold', 'HorizontalAlignment', 'center', 'Units', 'normalized');
  • 使用text函數添加副標題,Units', 'normalized'讓位置基于畫布比例(0-1),HorizontalAlignment' 'center'使文字居中。?

3. 透明度與邊緣處理

'FaceAlpha', 0.7, % 填充透明度
'EdgeColor', 'none', % 無邊緣線
  • 透明度設置讓下層「山脊」的輪廓隱約可見,增加層次感;去除邊緣線避免畫面雜亂。?

六、應用場景:山脊圖的「用武之地」?

山脊圖因其獨特的可視化效果,在多個領域都有出色表現:?

  • 生物學:展示不同物種的體長、體重分布差異。?
  • 市場調研:對比不同地區的消費者年齡、消費金額分布。?
  • 氣象學:呈現不同月份的溫度、降水量分布變化。?
  • 教育學:分析不同班級的成績分布形態(是否偏科、兩極分化等)。?
  • 金融學:可視化不同資產的收益率分布,識別風險差異。?

舉個例子:如果你是電商分析師,想對比 12 個月的用戶購買金額分布,就可以用山脊圖展示每個月的分布曲線,一眼看出哪些月份的購買金額均值更高、波動更大。?

七、常見問題與解決方案?

1. 「山脊」重疊過多怎么辦??

  • 原因:yOffset太小或f_normalized的歸一化系數太大(當前是 0.8,可減小到 0.6)。?
  • 解決:增大yOffset(如從 1.5 改為 2),或減小歸一化系數(如*0.6),降低「山脊」高度。?

2. 標簽被圖形遮擋怎么辦??

  • 原因:倒序循環時,標簽位置計算錯誤,或baseline + 0.3的偏移量不夠。?
  • 解決:確保循環是倒序(numSamples:-1:1),并適當調整標簽的 Y 坐標(如baseline + 0.5)。?

3. 顏色不夠區分怎么辦??

  • 解決:使用colororder(colors)調整顏色順序,或換用對比度更高的色階(如lines色階,但更適合少量樣本)。?

八、總結:動手打造你的專屬數據山脈?

通過今天的分享,我們不僅掌握了山脊圖的核心繪制邏輯,還學會了如何替換真實數據、調整可視化細節。從隨機數據生成到核密度估計,從顏色映射到標簽添加,每一步都是為了讓數據分布以最清晰、美觀的方式呈現。?

現在,輪到你動手實踐啦!💻 打開 MATLAB,替換成你的數據,調整參數,看看屬于你的「數據山脈」如何崛起。記得在遇到問題時回顧本文的「用戶數據替換指南」和「常見問題」,相信你一定能繪制出令人驚嘆的山脊圖!?

如果覺得本文有用,歡迎分享給身邊的數據分析小伙伴。下次我們將探討更多高級可視化技巧,記得關注哦~ 祝你繪圖愉快,數據可視化之路越走越順!🚀

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85590.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85590.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85590.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

跨境電商每周資訊—6.16-6.20

1. Instagram 在亞太地區逐漸超越 TikTok 在整個亞太地區,Instagram用戶數量正逐漸超過TikTok。預計2025年日本Instagram用戶數量將增至4440萬,印度今年用戶數量將增長10%,領跑亞太。與之形成對比的是,TikTok在一些國家增長速度放…

計算機網絡 網絡層:數據平面(一)

前一節學習了運輸層依賴于網絡層的主機到主機的通信服務,提供各種形式的進程到進程的通信。了解這種主機到主機通信服務的真實情況,是什么使得它工作起來的。 在本章和下一章,將學習網絡層實際是怎樣實現主機到主機的通信服務。與運輸層和應用…

Suna本地部署詳細教程

一、安裝基礎環境 # 1、創建環境 conda create -n suna python3.11.7# 2、激活虛擬環境 conda activate suna# 3、安裝jupyter和ipykernel pip install jupyter ipykernel# 4、將虛擬環境添加到jupyter # python -m ipykernel install --user --namemyenv --display-name"…

LeetCode 每日一題打卡|若谷的刷題日記 3day--最長連續序列

1.最長連續序列 題目: 給定一個未排序的整數數組 nums ,找出數字連續的最長序列(不要求序列元素在原數組中連續)的長度。 請你設計并實現時間復雜度為 O(n) 的算法解決此問題。 示例 1: 輸入:nums [1…

EfficientVLA:面向視覺-語言-動作模型無訓練的加速與壓縮

25年6月來自上海交大、哈工大、西安交大和電子科大(成都)的論文“EfficientVLA: Training-Free Acceleration and Compression for Vision-Language-Action Models”。 視覺-語言-動作 (VLA) 模型,特別是基于擴散的架構,展現出具…

wireshark抓包分析TCP數據包

1、直接從TCP的三次握手開始說起 三次握手就是客戶與服務器建立連接的過程 客戶向服務器發送SYN(SEQ=x)報文,然后就會進入SYN_SEND狀態服務器收到SYN報文之后,回應一個SYN(SEQ=y)ACK(ACK=x+1)報文,然后就會進入SYN_RECV狀態客戶收到服務器的SYN報文,回應一個ACK(AC…

同等學力申碩-計算機統考-歷年真題和備考經驗

同等學力申請碩士學位考試是比較適合在職人員的提升學位方式,了解過的人應該都知道,現在社會的競爭壓力越來越大,為了提高職業生存能力,提升學位在所難免。 一、已有計算機統考歷年真題資料 報名過同等學力申碩計算機專業的朋友都…

OSI網絡通信模型詳解

OSI 模型就是把這整個過程拆解成了 7 個明確分工的步驟,每一層只負責自己那一攤事兒,這樣整個系統才能順暢運轉,出了問題也容易找到“鍋”在誰那。 核心比喻:寄快遞 📦 想象你要把一份重要的禮物(你的數據…

C++ 檢測文件大小和文件傳輸

檢測文件的大小 你可以通過標準 C/C 的文件 API 很方便地獲取文件的字節大小&#xff0c;以下是幾種常用方法&#xff1a; ? 方法一&#xff1a;使用 stat() 函數&#xff08;推薦&#xff09; #include <sys/stat.h> #include <stdio.h>off_t get_file_size(co…

Ubuntu 中修改網卡 IP

在 Ubuntu 中修改網卡 IP 地址可以通過以下方法實現&#xff0c;具體取決于你使用的網絡管理工具&#xff08;如 netplan、ifconfig/ip 命令或傳統 interfaces 文件&#xff09;。以下是常見方法&#xff1a; 方法 1&#xff1a;使用 netplan&#xff08;Ubuntu 17.10 及更新版…

記錄學習three.js 為什么 .glTF 是更適合 Web 的 3D 模型格式?——從 .OBJ 到 .glTF 的轉變?

在上一篇中&#xff0c;我們介紹了如何在 Three.js 中加載 .OBJ 模型。如果你沒看過&#xff0c;建議先閱讀一下基礎內容。然而你很快會發現&#xff0c;.OBJ 雖然入門簡單&#xff0c;卻并不是 Web3D 場景中的最佳格式。 .OBJ 是什么&#xff1f; .OBJ 是最早期的3D交換格式之…

H遞歸函數.go

前言&#xff1a;遞歸函數是一種強大而又充滿魅力的編程技巧。它就像是一面神奇的鏡子&#xff0c;函數在其中能夠調用自身的倒影&#xff0c;從而以一種簡潔而優雅的方式解決許多復雜的問題。 目錄 一、遞歸函數是啥玩意兒 二、遞歸函數的優缺點 優點 缺點 三、遞歸函數…

軟件功能測試的測試標準

一、軟件功能測試行業標準概述 軟件功能測試行業標準是規范軟件測試流程、方法、工具及人員資質的準則&#xff0c;是確保軟件產品的功能性、可靠性、易用性等質量特性符合用戶需求。這些標準不僅為測試人員提供了明確的指導&#xff0c;也為軟件產品的質量控制提供了有力保障。…

EchoEar(喵伴):樂鑫發布與火山引擎扣子聯名 AI 智能體開發板

隨著生成式人工智能技術的快速發展&#xff0c;大語言模型 (LLM) 正逐步成為推動智能設備升級的核心力量。樂鑫科技攜手火山引擎扣子大模型團隊&#xff0c;共同推出智能 AI 開發套件 —— EchoEar&#xff08;喵伴&#xff09;。該套件以端到端開發為核心理念&#xff0c;構建…

圖像特征檢測算法SIFT

SIFT&#xff08;Scale - Invariant Feature Transform&#xff0c;尺度不變特征變換&#xff09;是一種計算機視覺領域的特征提取算法&#xff0c;具有重要的地位和廣泛的應用。 算法原理 構建高斯金字塔 &#xff1a; 為了實現多尺度檢測&#xff0c;SIFT 算法會構建高斯金…

光纖通道收發器:市場洞察、技術演進與未來機遇

一、引言 在數字化浪潮席卷全球的當下&#xff0c;數據存儲與傳輸的需求呈爆發式增長。光纖通道收發器作為高速、可靠數據存儲網絡&#xff08;如存儲區域網絡 SAN&#xff09;中的關鍵組件&#xff0c;發揮著至關重要的作用。它通過光纖實現服務器、存儲設備和交換機之間的數…

candence17.4如何設置兩個焊盤之間在TOP與BOTTOM可以存在兩根線

為什么要走兩根線&#xff1f; 為了過大電流&#xff0c;有時候就需要我們在TOP、BOTTOM兩個面走線&#xff0c;同時開窗&#xff0c;然后通過加錫的方式增加過流能力&#xff1b; 當然由于兩面都有導線&#xff0c;必然會存在過孔&#xff0c;而過孔的過流能力不僅與過孔孔徑…

Dify:參數調節,讓LLM從能用到好用的機制

前言 隨著大語言模型(LLM)在文本生成、智能對話、技術問答等前沿領域的深度滲透&#xff0c;參數精細化調節已成為開發者駕馭 AI 能力的核心必修課。 本文將系統的解釋溫度(Temperature)、核采樣(Top - P)、截斷采樣(Top - K)等關鍵參數的底層作用機制&#xff0c;結合多種場景…

防抖不同的實現

防抖&#xff08;Debounce&#xff09;&#xff1a;在事件被觸發后&#xff0c;延遲一段時間再執行函數。如果在延遲期間事件再次被觸發&#xff0c;則重新計時。常用于搜索框輸入、窗口大小調整等場景。 1.不安裝任何依賴和庫&#xff0c;編寫一個防抖的函數 在utils里面增加…

MySQL 數據庫索引詳解

一、索引是什么&#xff1f;能干嘛&#xff1f; 類比理解&#xff1a;索引就像書的目錄。比如你想查《哈利波特》中 “伏地魔” 出現的頁數&#xff0c;不用逐頁翻書&#xff0c;直接看目錄找關鍵詞就行。數據庫里的索引就是幫你快速找到數據的 “目錄”。 核心作用&#xff…