電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 94|回復(fù): 0
收起左側(cè)

MATLAB|科研繪圖|山脊圖

[復(fù)制鏈接]

171

主題

171

帖子

1312

積分

三級(jí)會(huì)員

Rank: 3Rank: 3

積分
1312
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2023-11-14 13:09:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
點(diǎn)擊上方藍(lán)字和“好玩的MATLAB”一起快樂(lè)玩耍吧!

好玩的matlab
帶你解鎖不一樣的matlab新玩法

今天介紹一下山脊圖,喜歡此推文的小伙伴們記得點(diǎn)贊+關(guān)注+分享!【尊重作者勞動(dòng)成果,轉(zhuǎn)載請(qǐng)注明推文鏈接和公眾號(hào)名】上周去逛了一下商店看見(jiàn)一個(gè)筆架

這突然讓我想起,這個(gè)不就像科研繪圖的山脊圖嘛,于是我打算用 MATLAB 復(fù)刻一個(gè)。


效果圖



山脊圖介紹山脊圖(Ridge Plot),也被稱為Joy Plot,是一種用于可視化數(shù)據(jù)分布的圖表,特別是用于顯示多個(gè)組的分布情況。在這種圖表中,每個(gè)組的數(shù)據(jù)分布都通過(guò)平滑的密度曲線來(lái)表示,這些曲線沿著垂直軸堆疊,形成類似山脊的視覺(jué)效果。山脊圖是核密度估計(jì)(KDE)的一個(gè)應(yīng)用,它提供了比傳統(tǒng)的條形圖或直方圖更平滑的數(shù)據(jù)分布視圖。
用途:山脊圖主要用于展示和比較不同組或類別內(nèi)數(shù)據(jù)的分布情況。它特別適合于以下情境:
比較多個(gè)分布:當(dāng)需要展示和比較多組數(shù)據(jù)的分布形狀時(shí),山脊圖能夠直觀地展示出分布之間的差異。
展現(xiàn)趨勢(shì)變化:在時(shí)間序列數(shù)據(jù)中,山脊圖可以用來(lái)展示數(shù)據(jù)隨時(shí)間的變化趨勢(shì)。
優(yōu)化空間利用:通過(guò)堆疊的方式,山脊圖能在有限的空間內(nèi)展示大量的分布信息。
缺點(diǎn):
可讀性:對(duì)于不熟悉這種圖表的觀眾來(lái)說(shuō),山脊圖可能難以理解和解讀。
疊加問(wèn)題:當(dāng)曲線重疊較多時(shí),可能會(huì)導(dǎo)致圖表的某些部分難以區(qū)分。
數(shù)據(jù)量限制:對(duì)于數(shù)據(jù)量非常大的數(shù)據(jù)集,山脊圖可能不那么有效,因?yàn)檫^(guò)多的曲線會(huì)使圖表變得雜亂。
應(yīng)用場(chǎng)景
時(shí)間序列分析:在金融、經(jīng)濟(jì)、氣象等領(lǐng)域,用于展示某個(gè)變量隨時(shí)間的變化趨勢(shì)。
社會(huì)科學(xué):比如在選舉數(shù)據(jù)分析中,展示不同候選人或黨派在不同地區(qū)或人群中的支持率分布。
生物醫(yī)學(xué):用于展示不同實(shí)驗(yàn)組或治療方法下的生物統(tǒng)計(jì)數(shù)據(jù)分布。
繪圖教程線條山脊圖
  • data = randn(100,12)+[ 20 22 24 26 28 31 30 28 26 24 22 20];lgLable= {'January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December'};colors=makeColorMap([0,0,0;1,1,1],12);figure('Position',[476 246 511 620])p=0.15;yTick=(1:size(data, 2))*p;for i = 1:size(data, 2)    [f, x] = ksdensity(data(:, i));    f=f+i*p;    pHandle=plot(x, f, 'LineWidth', 1.5,'color',colors(i,:));    hold on;    yline(yTick(i),'-.','LineWidth',1,'Color',pHandle.Color,'HandleVisibility','off')endgrid off;box off;legend(lgLable,'box','on','Color',[1,1,1]*0.95,'EdgeColor','none');set(gca, 'YTick',yTick , 'YTickLabel',lgLable,'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname','Times new Roman','color',[1,1,1]*0.9);xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');hold off;

    填充山脊圖
  • data = randn(100,12)+[ 20 22 24 26 28 31 30 28 26 24 22 20];lgLable= {'January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December'};% colors=makeColorMap(winter,size(data, 2));colors=makeColorMap(jet,size(data, 2));figure('Position',[476 246 511 620])p =0.2;hold on;for i = size(data, 2):-1:1    [f, x] = ksdensity(data(:, i));    fShifted = f + i * p;    pHandle = plot(x, fShifted,'color',colors(i,:),'LineWidth', 1.5,'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'Color', colors(i,:),'HandleVisibility', 'off')    Xfill = [x, fliplr(x)];    Yfill = [fShifted, ones(1, length(x)) * i * p];    fill(Xfill, Yfill, pHandle.Color, 'EdgeColor', 'none', 'FaceAlpha', 0.3);endyTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, ...    'YTickLabel', lgLable, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname','Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');ax = gca;hold off;?

    3D填充山脊圖
  • data = randn(100,12)+[ 20 22 24 26 28 31 30 28 26 24 22 20];lgLabel= {'January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December'};p = 0.2;xTick=(1:size(data, 2))*p;figure('Position',[476 246 511 620])hold on;colors=makeColorMap(hsv,size(data, 2));legendHandles = zeros(size(data, 2), 1);for i = 1:size(data, 2)    [f, y] = ksdensity(data(:, i));    xShifted = i * p;    plot3(xShifted * ones(size(f)), y, f, 'LineWidth', 1.5, 'Color', colors(i,:), 'HandleVisibility', 'off');    Yfill = [y, fliplr(y)];    Xfill = [xShifted * ones(1, length(y)), xShifted * ones(1, length(y))];    Zfill = [f, zeros(size(f))];    legendHandles(i)  = fill3(Xfill, Yfill, Zfill, colors(i,:), 'EdgeColor', 'none', 'FaceAlpha', 0.3); endgrid off;box on;legend(lgLabel,'box','on','Color',[1,1,1]*0.95,'EdgeColor','none','FontName','Times New Roman','location','best');set(gca, 'XTick',xTick, 'XTickLabel',lgLabel,'FontName','Times New Roman','linewidth',1)xlabel('XXXX-Value');ylabel('YYYY-Value');zlabel('ZZZ-Value');title('Ridge Plot');view([-83.4000   71.6830])hold off;

    不同核山脊圖、添加邊際散點(diǎn)密度
  • data = randn(100,3)+[ 20  24 28];colors=makeColorMap(jet,size(data, 2));figure('Position',[476 246 511 620])p=0;hold on;yTick=(1:size(data, 2))*p;lineLength = 0.02; % 豎線的長(zhǎng)度f(wàn)or i = size(data, 2):-1:1    [f, x] = ksdensity(data(:, i));    fShifted = f + i * p;    pHandle = plot(x, fShifted, 'color', colors(i,:), 'LineWidth', 1.5, 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'Color', colors(i,:), 'HandleVisibility', 'off');    Xfill = [x, fliplr(x)];    Yfill = [fShifted, ones(1, length(x)) * i * p];    fill(Xfill, Yfill, pHandle.Color, 'EdgeColor', 'none', 'FaceAlpha', 0.3);    for j = 1:length(data(:, i))        line([data(j, i), data(j, i)], [i * p, i * p + lineLength], 'Color', pHandle.Color, 'LineWidth', 1);    endendgrid off;box off;ax=gca;set(ax,'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname','Times new Roman','color',[1,1,1]*0.9);ax.YLim=[0,1];ax.XLim=[15,32];xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');hold off;

    橫坐標(biāo)方向、全局漸變的散點(diǎn)圖
  • data = randn(100,12)+[ 20 22 24 26 28 31 30 28 26 24 22 20];lgLabel={'January', 'February', 'March', 'April', 'May', 'June',    'July', 'August', 'September', 'October', 'November', 'December'};p = 0.2;numColors = 256;% 創(chuàng)建一個(gè)從紫色到紅色再到黃色的顏色映射colorMap =makeColorMap([0.1490    0.0353    0.5608;0.7305    0.2500    0.4922;0.9569    0.9490    0.1765],numColors);% 計(jì)算全局的x軸范圍xMin = min(data, [], 'all');xMax = max(data, [], 'all');figure('Position',[476 246 511 620])hold on;for i = size(data, 2):-1:1    [f(i,:), x] = ksdensity(data(:, i), 'Kernel', 'triangle');    fShifted = f(i,:) + i * p; % 偏移每個(gè)分布    plot(x, fShifted, 'LineWidth', 1.5, 'color', 'k', 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'HandleVisibility', 'off');    for j = 1:length(x)-1        Xfill = [x(j), x(j+1), x(j+1), x(j)];        Yfill = [i * p, i * p, fShifted(j+1), fShifted(j)];        % 計(jì)算當(dāng)前點(diǎn)的顏色比例        colorRatio = (x(j) - xMin) / (xMax - xMin);        colorIdx = min(numColors, max(1, round(colorRatio * (numColors - 1)) + 1));        fill(Xfill, Yfill, colorMap(colorIdx, :), 'EdgeColor', 'none', 'FaceAlpha', 0.9);    endend% 設(shè)置軸標(biāo)簽和標(biāo)題yTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, ...    'YTickLabel', lgLabel, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname','Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');% 設(shè)置顏色條colormap(colorMap);cBar = colorbar;cBar.TickDirection = 'out';cBar.LineWidth = 1;cBar.TickLength = 0.02;cBar.FontName = 'Times new Roman';caxis([xMin,xMax]);hold off;

    橫坐標(biāo)方向、單核漸變圖
  • data = randn(100,12) + [20 22 24 26 28 31 30 28 26 24 22 20];lgLabel = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'};numColors = 256; % 顏色數(shù)量colors = jet(numColors); % 使用jet顏色映射figure('Position',[476 246 511 620])p = 0.2;hold on;for i = size(data, 2):-1:1    [f, x] = ksdensity(data(:, i));    fShifted = f + i * p;    plot(x, fShifted, 'LineWidth', 1.5, 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'HandleVisibility', 'off');    colorGradient = linspace(1, numColors, length(x));    for j = 1:length(x)-1        Xfill = [x(j), x(j+1), x(j+1), x(j)];        Yfill = [i * p, i * p, fShifted(j+1), fShifted(j)];        fill(Xfill, Yfill, colors(round(colorGradient(j)), :), 'EdgeColor', 'none', 'FaceAlpha', 0.7);    endendyTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, 'YTickLabel', lgLabel, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname', 'Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');colormap(colors);cBar = colorbar;cBar.TickDirection = 'out';cBar.LineWidth = 1;cBar.TickLength = 0.02;cBar.FontName = 'Times new Roman';hold off;

    每個(gè)山脊圖設(shè)置不同顏色,且添加邊際散點(diǎn)圖
  • data = randn(100,12)+[ 20 22 24 26 28 31 30 28 26 24 22 20];lgLable = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'};figure('Position', [476 246 511 620])p = 0.3;lineLength = 0.04; % 豎線的長(zhǎng)度colors=makeColorMap(hsv,size(data, 2));hold on;for i = size(data, 2):-1:1    [f, x] = ksdensity(data(:, i));    fShifted = f + i * p;    pHandle = plot(x, fShifted, 'color', colors(i,:), 'LineWidth', 1.5, 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'Color', colors(i,:), 'HandleVisibility', 'off');    Xfill = [x, fliplr(x)];    Yfill = [fShifted, ones(1, length(x)) * i * p];    fill(Xfill, Yfill, pHandle.Color, 'EdgeColor', 'none', 'FaceAlpha', 0.3);    for j = 1:length(data(:, i))        line([data(j, i), data(j, i)], [i * p, i * p + lineLength], 'Color', 'k', 'LineWidth', 1);    endendyTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, ...    'YTickLabel', lgLable, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname', 'Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');

    每個(gè)山脊圖設(shè)置不同顏色單核橫向顏色漸變
  • data = randn(100,12)+[ 20 22 24 26 28 31 30 28 26 24 22 20];lgLabel = {'January', 'February', 'March', 'April', 'May', 'June', ...    'July', 'August', 'September', 'October', 'November', 'December'};p = 0.2;numColors = 256;% 創(chuàng)建12個(gè)不同的顏色映射,每個(gè)月一個(gè)colorMaps = cell(1, 12);colorList={parula,turbo,hsv,hot,cool,spring,summer,autumn,winter,gray,bone,copper,pink,jet,lines,colorcube,prism,flag};for i = 1:12    colorMaps{i} = makeColorMap(colorList{i}, numColors);end% 計(jì)算全局的x軸范圍xMin = min(data, [], 'all');xMax = max(data, [], 'all');figure('Position', [476 246 511 620])hold on;for i = size(data, 2):-1:1    [f(i,:), x] = ksdensity(data(:, i), 'Kernel', 'triangle');    fShifted = f(i,:) + i * p; % 偏移每個(gè)分布    plot(x, fShifted, 'LineWidth', 1.5, 'color', 'k', 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'HandleVisibility', 'off');    currentColorMap = colorMaps{i};    for j = 1:length(x)-1        Xfill = [x(j), x(j+1), x(j+1), x(j)];        Yfill = [i * p, i * p, fShifted(j+1), fShifted(j)];        colorRatio = (x(j) - xMin) / (xMax - xMin);        colorIdx = min(numColors, max(1, round(colorRatio * (numColors - 1)) + 1));        fill(Xfill, Yfill, currentColorMap(colorIdx, :), 'EdgeColor', 'none', 'FaceAlpha', 0.9);    endendyTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, ...    'YTickLabel', lgLabel, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname', 'Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');hold off;

    山脊圖的 Y值映射顏色變化
  • data = randn(100,12) + [20 22 24 26 28 31 30 28 26 24 22 20];lgLabel = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'};numColors = 100; % 顏色數(shù)量colors =makeColorMap(jet, numColors);figure('Position',[476 246 511 620])p = 0.2;hold on;for i = size(data, 2):-1:1    [f, x] = ksdensity(data(:, i));    fShifted = f + i * p;    plot(x, fShifted, 'LineWidth', 1.5, 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'HandleVisibility', 'off');    % 計(jì)算整個(gè)分布的最小和最大縱坐標(biāo)    minY = min(fShifted);    maxY = max(fShifted);    for j = 1:length(x)-1        Xfill = [x(j), x(j+1), x(j+1), x(j)];        Yfill = [i * p, i * p, fShifted(j+1), fShifted(j)];        avgY = mean(Yfill(3:4));         colorIdx = round(((avgY - minY) / (maxY - minY)) * (numColors - 1)) + 1;        fill(Xfill, Yfill, colors(colorIdx, :), 'EdgeColor', 'none', 'FaceAlpha', 0.6);    endendyTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, 'YTickLabel', lgLabel, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname', 'Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');colormap(colors);cBar = colorbar;cBar.TickDirection = 'out';cBar.LineWidth = 1;cBar.TickLength = 0.02;cBar.FontName = 'Times new Roman';hold off;


    四分位點(diǎn)
  • data = randn(100,12) + [20 22 24 26 28 31 30 28 26 24 22 20];lgLabel = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'};colors = makeColorMap(jet, size(data, 2));figure('Position', [476 246 511 620])p = 0.2;hold on;for i = size(data, 2):-1:1    [f, x] = ksdensity(data(:, i));    fShifted = f + i * p;    pHandle = plot(x, fShifted, 'color', colors(i,:), 'LineWidth', 1.5, 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'Color', colors(i,:), 'HandleVisibility', 'off')    Xfill = [x, fliplr(x)];    Yfill = [fShifted, ones(1, length(x)) * i * p];    fill(Xfill, Yfill, pHandle.Color, 'EdgeColor', 'none', 'FaceAlpha', 0.3);    % 計(jì)算并標(biāo)記四分位點(diǎn)    quartiles = quantile(data(:, i), [0.25 0.50 0.75]);    for q = quartiles        [~, idx] = min(abs(x-q));        plot(q, fShifted(idx), 'o', 'MarkerFaceColor', pHandle.Color, 'MarkerEdgeColor', 'k');    endendyTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, ...    'YTickLabel', lgLabel, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname', 'Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');hold off;

  • data = randn(100,12) + [20 22 24 26 28 31 30 28 26 24 22 20];lgLabel = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'};colors = makeColorMap(jet, size(data, 2));figure('Position', [476 246 511 620])p = 0.2;hold on;for i = size(data, 2):-1:1    [f, x] = ksdensity(data(:, i));    fShifted = f + i * p;    pHandle = plot(x, fShifted, 'color', colors(i,:), 'LineWidth', 1.5, 'HandleVisibility', 'off');    yline(i * p, '-.', 'LineWidth', 1, 'Color', colors(i,:), 'HandleVisibility', 'off');    Xfill = [x, fliplr(x)];    Yfill = [fShifted, ones(1, length(x)) * i * p];    fill(Xfill, Yfill, pHandle.Color, 'EdgeColor', 'none', 'FaceAlpha', 0.3);    % 計(jì)算并標(biāo)記四分位點(diǎn),并繪制豎線    quartiles = quantile(data(:, i), [0.25 0.50 0.75]);    for q = quartiles        [~, idx] = min(abs(x-q));        plot(q, fShifted(idx), 'o', 'MarkerFaceColor', pHandle.Color, 'MarkerEdgeColor', 'k');        line([q q], [fShifted(idx) i * p], 'Color', pHandle.Color, 'LineStyle', '-.','LineWidth', 1);    endendyTick = (1:size(data, 2)) * p;set(gca, 'YTick', yTick, ...    'YTickLabel', lgLabel, ...    'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ...    'fontname', 'Times new Roman');xlabel('XXXX-Value');ylabel('YYYY-Value');title('Ridge Plot');hold off;

    其中makeColorMap函數(shù)代碼之前「一張圖搞定繪圖配色問(wèn)題」有詳細(xì)介紹。
    - -THE END- -

    源碼下載:gitee下載:https://gitee.com/iDMatlab/ridgePlot

    QQ 群下載:

    fileexchange 下載:


    參考資料:
    【1】https://it.sohu.com/a/704677145_121123706


    送書(shū)活動(dòng)



    包郵贈(zèng)送 「北京大學(xué)出版社贊助《3D科研繪圖與學(xué)術(shù)圖表繪制從入門到精通》

    專業(yè)級(jí)3D科研繪圖與學(xué)術(shù)圖表繪制指南:以“設(shè)計(jì)基本概念+軟件底層原理+案例實(shí)際操作”的思路進(jìn)行全方位講解,涵蓋化學(xué)、材料學(xué)、生物醫(yī)學(xué)等領(lǐng)域的科學(xué)可視化的藝術(shù)化表達(dá)
    實(shí)例豐富:我們涵蓋各類繪圖軟件與工具,讓你能夠自如運(yùn)用不同技術(shù)繪制出高質(zhì)量的圖表。內(nèi)容全面:全流程講解3D科研繪圖與學(xué)術(shù)圖表繪制的方法,有效填補(bǔ)了現(xiàn)有同類型參考書(shū)的空白。經(jīng)驗(yàn)總結(jié):作者多年一線研發(fā)實(shí)戰(zhàn)經(jīng)驗(yàn)全面歸納整理,毫無(wú)保留分享技術(shù)要領(lǐng)。大咖力薦:多位大型科技公司技術(shù)高管和高校相關(guān)領(lǐng)域教研專家推薦。
  • 全彩印刷:圖表案例精彩呈現(xiàn),帶來(lái)良好的閱讀體驗(yàn),方便理解和學(xué)習(xí)。
    了解更多
    【抽獎(jiǎng)方式及滿足條件】:
    1.關(guān)注「好玩的MATLAB 」公眾號(hào)和視頻號(hào)

    2.給本文點(diǎn)【】+【在看】;
    3.留言區(qū)評(píng)論點(diǎn)贊最多的前2名。
    4.本活動(dòng)只針對(duì)從未獲過(guò)獎(jiǎng)的同學(xué),之前獲過(guò)獎(jiǎng)的小伙伴,不用參加。
    同時(shí)滿足上述4個(gè)條件的讀者朋友,包郵贈(zèng)送一本.
    【開(kāi)獎(jiǎng)時(shí)間】:2023年11月15日中午12點(diǎn)
    【領(lǐng)獎(jiǎng)方式】:在開(kāi)獎(jiǎng)時(shí)加小編私人微信:idmatlab
    掃一掃加管理員微信

  • 發(fā)表回復(fù)

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表