MATLAB|科研绘图|山脊图
目录
公众号:
效果图
山脊图介绍
山脊图(Ridge Plot),也被称为Joy Plot,是一种用于可视化数据分布的图表,特别是用于显示多个组的分布情况。在这种图表中,每个组的数据分布都通过平滑的密度曲线来表示,这些曲线沿着垂直轴堆叠,形成类似山脊的视觉效果。山脊图是核密度估计(KDE)的一个应用,它提供了比传统的条形图或直方图更平滑的数据分布视图。
用途:山脊图主要用于展示和比较不同组或类别内数据的分布情况。它特别适合于以下情境:
- 比较多个分布:当需要展示和比较多组数据的分布形状时,山脊图能够直观地展示出分布之间的差异。
- 展现趋势变化:在时间序列数据中,山脊图可以用来展示数据随时间的变化趋势。
- 优化空间利用:通过堆叠的方式,山脊图能在有限的空间内展示大量的分布信息。
缺点:
- 可读性:对于不熟悉这种图表的观众来说,山脊图可能难以理解和解读。
- 叠加问题:当曲线重叠较多时,可能会导致图表的某些部分难以区分。
- 数据量限制:对于数据量非常大的数据集,山脊图可能不那么有效,因为过多的曲线会使图表变得杂乱。
应用场景:
- 时间序列分析:在金融、经济、气象等领域,用于展示某个变量随时间的变化趋势。
- 社会科学:比如在选举数据分析中,展示不同候选人或党派在不同地区或人群中的支持率分布。
- 生物医学:用于展示不同实验组或治疗方法下的生物统计数据分布。
绘图教程
线条山脊图
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') end grid 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); end yTick = (1:size(data, 2)) * p; ax = gca; hold off; set(ax, 'YTick', yTick, ... 'YTickLabel', lgLable, ... 'LineWidth', 1.5, 'XMinorTick', 'on', 'TickDir', 'out', ... 'fontname','Times new Roman'); xlabel('XXXX-Value'); ylabel('YYYY-Value'); title('Ridge Plot');
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); end grid 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;
不同核山脊图、添加边际散点密度
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; % 竖线的长度 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', pHandle.Color, 'LineWidth', 1); end end grid 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;
横坐标方向、全局渐变的散点图
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; % 创建一个从紫色到红色再到黄色的颜色映射 colorMap =makeColorMap([0.1490 0.0353 0.5608;0.7305 0.2500 0.4922;0.9569 0.9490 0.1765],numColors); % 计算全局的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; % 偏移每个分布 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)]; % 计算当前点的颜色比例 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); end end % 设置轴标签和标题 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'); % 设置颜色条 colormap(colorMap); cBar = colorbar; cBar.TickDirection = 'out'; cBar.LineWidth = 1; cBar.TickLength = 0.02; cBar.FontName = 'Times new Roman'; caxis([xMin,xMax]); 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'}; numColors = 256; % 颜色数量 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); end end 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'); colormap(colors); cBar = colorbar; cBar.TickDirection = 'out'; cBar.LineWidth = 1; cBar.TickLength = 0.02; cBar.FontName = 'Times new Roman'; 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'}; figure('Position', [476 246 511 620]) p = 0.3; lineLength = 0.04; % 竖线的长度 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); end end yTick = (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');
每个山脊图设置不同颜色单核横向颜色渐变
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; % 创建12个不同的颜色映射,每个月一个 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 % 计算全局的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; % 偏移每个分布 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); end end 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'); 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; % 颜色数量 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'); % 计算整个分布的最小和最大纵坐标 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); end end 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'); colormap(colors); cBar = colorbar; cBar.TickDirection = 'out'; cBar.LineWidth = 1; cBar.TickLength = 0.02; cBar.FontName = 'Times new Roman'; 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); % 计算并标记四分位点 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'); end end 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'); 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); % 计算并标记四分位点,并绘制竖线 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); end end 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'); hold off;
其中makeColorMap函数代码之前「一张图搞定绘图配色问题」有详细介绍。
源码:
posted on 2023-11-14 14:04 好玩的MATLAB 阅读(618) 评论(0) 编辑 收藏 举报 来源