MATLAB | 绘图复刻(二十五)| 环形柱状图+核密度面积图

大家好久不见,吃喝玩乐后又来写推送啦,本期复刻的图像来自:

  • Li, G., Su, X., Yang, Y. et al. Interpretability-guided RNA N 6 \text{N}^6 N6-methyladenosine modification site prediction with invertible neural networks. Commun Biol 8, 1022 (2025). https://doi.org/10.1038/s42003-025-08265-8

的 fig.5 中的 e、f 图:

复刻效果:

还是非常好看的:

正文

数据准备

这里展示一下每种数据大概长啥样:大家可以自行从excel、mat或者txt文件读取:

matlab 复制代码
clc; clear
% 原图环形柱状图柱子长度显著性水平,顶部的数字表示富集基因的数量
% 这里我们直接随便编一下

Name = {'GeneXXXXXX-A', 'GeneXYYYYYYYY-B', 'GeneXXXXXXYYY-C', 'GeneXXXXXXYY-D', ...
        'GeneXXXXXX-E', 'GeneXXXXXXXXX-F', 'GeneXXXXXX-G', 'GeneXXXXXX-H', ...
        'GeneABCABCXXXXXX-I', 'GeneXXXXXX-J'};
Value = [31, 17, 17, 21, 20, 18, 11, 15, 7, 9];
Len = Value; % 我们这里直接长度和数字统一,可自行换成其他数值
Class = [1, 2, 2, 1, 1, 2, 2, 2, 2, 2];
ClassName = {'SLAN-related', 'Other'};

% 随机生成了一些 0-80 的数字,并随机将其分类(类1、类2)
rng(1)
Num = [randi([0, 80], [1, 50]), randi([10, 20], [1, 40]), randi([75, 80], [1, 10])];
NumClass = randi([1, 2], [1, 100]);


% 配色,这里只有两种颜色,如果类更多的话要增添更多颜色
CList = [235,173,189; 
        123,166,211]./255; 

原文中柱状图的柱子长度和标注的数值是不一样的,柱子长度代表显著性水平,顶部的数字表示富集基因的数量,我们弄一样或者不一样都可以。比如我们这段代码里面标注的数值和柱子长度就是对应的。变量 ClassNumClass 这里用来存储分类情况的数组,比如分了两类的话,其中的数值就只有1和2。

环形柱状图绘制

比较新的版本可以直接用极坐标区域相关函数绘制会非常方便,这里为了尽量照顾更多的版本,就硬画了网格线和柱子:

matlab 复制代码
figure('Units','normalized', 'Position',[.1,.2,.7,.7]);
%% 环形柱状图
ax1 = axes('Parent',gcf, 'Position',[.05,.1,.9,.8], 'DataAspectRatio',[1,1,1], ...
    'XLim', [-2, 1], 'YLim', [-1,1], 'NextPlot','add', 'XColor','none', 'YColor','none');
N = length(Value); M = max(Len);
% 绘制环形柱状图网格
tt = linspace(pi/2, -pi/2, 100); xx = cos(tt); yy = sin(tt);
XX = repmat([xx.'; nan], [1, N]).*repmat(((1:N) + .5)./(N + .5), [101, 1]);
YY = repmat([yy.'; nan], [1, N]).*repmat(((1:N) + .5)./(N + .5), [101, 1]);
plot(XX(:), YY(:), 'LineWidth',1, 'Color',[1,1,1].*.9)
th = [pi/2, -pi/2, pi/6, -pi/6];
XX = [th.*0; cos(th); th.*nan];
YY = [th.*0; sin(th); th.*nan];
plot(XX(:), YY(:), 'LineWidth',1, 'Color',[1,1,1].*.9)
% 绘制柱状图
for i = 1:N
    R = (N - i + 1)./(N + .5); r = .3./(N + .5);
    TT = (tt - pi/2).*.8.*Len(i)./M + pi/2;
    XX = [cos(TT).*(R + r), cos(TT(end:-1:1)).*(R - r)];
    YY = [sin(TT).*(R + r), sin(TT(end:-1:1)).*(R - r)];
    fill(XX, YY, CList(Class(i),:), 'LineWidth',1.5)
    text(cos(TT(end)).*R + sin(TT(end))./(N)./2, sin(TT(end)).*R - cos(TT(end))./(N)./2, ...
        num2str(Value(i)), 'HorizontalAlignment','center', 'FontName','Arial', 'FontSize',13)
    text(-.05, R, Name{i}, 'HorizontalAlignment','right', 'FontName','Arial', 'FontSize',13)
end

for i = 1:max(Class)
    lgdHdl1(i) = fill([115,108,97,110,100], [97,114,101,114,32], CList(Class(i),:), 'LineWidth',1.5);
end
lgd1 = legend(lgdHdl1, ClassName, 'Box','off', 'FontName','Arial', ...
    'FontSize',16, 'FontWeight','bold', 'Location','northwest');

核密度图绘制

matlab 复制代码
ax2 = axes('Parent',gcf, 'Position',[.18,.1,.42,.4], 'NextPlot','add', ...
    'XLim', [-20,100], 'LineWidth',1.5, 'Box','on', 'TickLength',[.001,0], ...
    'TickDir','out', 'FontSize',13);
xlabel(ax2, 'XXXX-XXXX-xxxxxxxx', 'FontName','Arial', 'FontSize',16)
ylabel(ax2, 'Density', 'FontName','Arial', 'FontSize',16)
xline(40, 'LineWidth',1, 'Alpha',1, 'LineStyle','--');

for i = 1:max(NumClass)
    x = Num(NumClass == i);
    [f, xi] = ksdensity(x);
    lgdHdl2(i) = area(xi, f, 'FaceColor',CList(i,:), 'EdgeColor',CList(i,:), 'FaceAlpha',.5);
    lgdtxt{i} = ['Mean counts: ' ,num2str(round(mean(x)))];
end
lgd2 = legend(lgdHdl2, ClassName, 'Box','off', 'FontName','Arial', ...
    'FontSize',16, 'Location','northeast');

完整代码

完整代码(两类)

matlab 复制代码
% 复刻自 | https://www.nature.com/articles/s42003-025-08265-8 
% + Li, G., Su, X., Yang, Y. et al. 
%   Interpretability-guided RNA N6-methyladenosine modification site prediction 
%   with invertible neural networks. Commun Biol 8, 1022 (2025). 
%   https://doi.org/10.1038/s42003-025-08265-8

clc; clear
% 原图环形柱状图柱子长度显著性水平,顶部的数字表示富集基因的数量
% 这里我们直接随便编一下

Name = {'GeneXXXXXX-A', 'GeneXYYYYYYYY-B', 'GeneXXXXXXYYY-C', 'GeneXXXXXXYY-D', ...
        'GeneXXXXXX-E', 'GeneXXXXXXXXX-F', 'GeneXXXXXX-G', 'GeneXXXXXX-H', ...
        'GeneABCABCXXXXXX-I', 'GeneXXXXXX-J'};
Value = [31, 17, 17, 21, 20, 18, 11, 15, 7, 9];
Len = Value; % 我们这里直接长度和数字统一,可自行换成其他数值
Class = [1, 2, 2, 1, 1, 2, 2, 2, 2, 2];
ClassName = {'SLAN-related', 'Other'};

% 随机生成了一些 0-80 的数字,并随机将其分类(类1、类2)
rng(1)
Num = [randi([0, 80], [1, 50]), randi([10, 20], [1, 40]), randi([75, 80], [1, 10])];
NumClass = randi([1, 2], [1, 100]);



% 配色,这里只有两种颜色,如果类更多的话要增添更多颜色
CList = [235,173,189; 
        123,166,211]./255; 


%% 开始绘图 ================================================================
figure('Units','normalized', 'Position',[.1,.2,.7,.7]);
%% 环形柱状图
ax1 = axes('Parent',gcf, 'Position',[.05,.1,.9,.8], 'DataAspectRatio',[1,1,1], ...
    'XLim', [-2, 1], 'YLim', [-1,1], 'NextPlot','add', 'XColor','none', 'YColor','none');
N = length(Value); M = max(Len);
% 绘制环形柱状图网格
tt = linspace(pi/2, -pi/2, 100); xx = cos(tt); yy = sin(tt);
XX = repmat([xx.'; nan], [1, N]).*repmat(((1:N) + .5)./(N + .5), [101, 1]);
YY = repmat([yy.'; nan], [1, N]).*repmat(((1:N) + .5)./(N + .5), [101, 1]);
plot(XX(:), YY(:), 'LineWidth',1, 'Color',[1,1,1].*.9)
th = [pi/2, -pi/2, pi/6, -pi/6];
XX = [th.*0; cos(th); th.*nan];
YY = [th.*0; sin(th); th.*nan];
plot(XX(:), YY(:), 'LineWidth',1, 'Color',[1,1,1].*.9)
% 绘制柱状图
for i = 1:N
    R = (N - i + 1)./(N + .5); r = .3./(N + .5);
    TT = (tt - pi/2).*.8.*Len(i)./M + pi/2;
    XX = [cos(TT).*(R + r), cos(TT(end:-1:1)).*(R - r)];
    YY = [sin(TT).*(R + r), sin(TT(end:-1:1)).*(R - r)];
    fill(XX, YY, CList(Class(i),:), 'LineWidth',1.5)
    text(cos(TT(end)).*R + sin(TT(end))./(N)./2, sin(TT(end)).*R - cos(TT(end))./(N)./2, ...
        num2str(Value(i)), 'HorizontalAlignment','center', 'FontName','Arial', 'FontSize',13)
    text(-.05, R, Name{i}, 'HorizontalAlignment','right', 'FontName','Arial', 'FontSize',13)
end

for i = 1:max(Class)
    lgdHdl1(i) = fill([115,108,97,110,100], [97,114,101,114,32], CList(Class(i),:), 'LineWidth',1.5);
end
lgd1 = legend(lgdHdl1, ClassName, 'Box','off', 'FontName','Arial', ...
    'FontSize',16, 'FontWeight','bold', 'Location','northwest');

%% 核密度图
ax2 = axes('Parent',gcf, 'Position',[.18,.1,.42,.4], 'NextPlot','add', ...
    'XLim', [-20,100], 'LineWidth',1.5, 'Box','on', 'TickLength',[.001,0], ...
    'TickDir','out', 'FontSize',13);
xlabel(ax2, 'XXXX-XXXX-xxxxxxxx', 'FontName','Arial', 'FontSize',16)
ylabel(ax2, 'Density', 'FontName','Arial', 'FontSize',16)
xline(40, 'LineWidth',1, 'Alpha',1, 'LineStyle','--');

for i = 1:max(NumClass)
    x = Num(NumClass == i);
    [f, xi] = ksdensity(x);
    lgdHdl2(i) = area(xi, f, 'FaceColor',CList(i,:), 'EdgeColor',CList(i,:), 'FaceAlpha',.5);
    lgdtxt{i} = ['Mean counts: ' ,num2str(round(mean(x)))];
end
lgd2 = legend(lgdHdl2, ClassName, 'Box','off', 'FontName','Arial', ...
    'FontSize',16, 'Location','northeast');

完整代码(更多类和更多配色)

写了一个例子,能更清晰展示怎么画分更多类的图:实际上有变动的只有前半部分。后面代码一模一样。

matlab 复制代码
% 复刻自 | https://www.nature.com/articles/s42003-025-08265-8 
% + Li, G., Su, X., Yang, Y. et al. 
%   Interpretability-guided RNA N6-methyladenosine modification site prediction 
%   with invertible neural networks. Commun Biol 8, 1022 (2025). 
%   https://doi.org/10.1038/s42003-025-08265-8

clc; clear
% 原图环形柱状图柱子长度显著性水平,顶部的数字表示富集基因的数量
% 这里我们直接随便编一下

Name = {'GeneXXXXXX-A', 'GeneXYYYYYYYY-B', 'GeneXXXXXXYYY-C', 'GeneXXXXXXYY-D', ...
        'GeneXXXXXX-E', 'GeneXXXXXXXXX-F', 'GeneXXXXXX-G', 'GeneXXXXXX-H', ...
        'GeneABCABCXXXXXX-I', 'GeneXXXXXX-J'};
Value = [31, 17, 17, 21, 20, 18, 11, 15, 7, 9];
Len = 10:-1:1; % 我们这里直接长度和数字统一,可自行换成其他数值
Class = [1, 2, 3, 4, 4, 2, 2, 1, 1, 2];
ClassName = {'Class-A','Class-B','Class-C','Class-D'};

% 随机生成了一些 0-80 的数字,并随机将其分类(类1、类2、类3、类4)
rng(2)
Num = [randi([0, 80], [1, 50]), randi([10, 20], [1, 40]), randi([75, 80], [1, 10])];
NumClass = randi([1, 4], [1, 100]);

% 配色,如果类更多的话要增添更多颜色
CList = [0.3961    0.6863    0.9529
    0.3686    0.6039    0.6118
    0.9725    0.8039    0.3137
    0.5020    0.4706    0.2902]; 
% CList = [0.0157    0.5412    0.7490
%     0.2784    0.3098    0.2431
%     0.9490    0.7176    0.0196
%     0.6510    0.3098    0.0118
%     0.7490    0.1882    0.1882];
% CList = [0.0745    0.1922    0.4902
%     0.4941    0.6549    0.8275
%     0.5216    0.8275    0.7647
%     0.8510    0.5725    0.4745
%     0.9686    0.3176    0.0275];
% CList = [0.1647    0.2471    0.4314
%     0.2431    0.5725    0.8784
%     0.7529    0.8078    0.8196
%     0.9882    0.8275    0.2941
%     0.9686    0.5804    0.0353];


%% 开始绘图 ================================================================
figure('Units','normalized', 'Position',[.1,.2,.7,.7]);
%% 环形柱状图
ax1 = axes('Parent',gcf, 'Position',[.05,.1,.9,.8], 'DataAspectRatio',[1,1,1], ...
    'XLim', [-2, 1], 'YLim', [-1,1], 'NextPlot','add', 'XColor','none', 'YColor','none');
N = length(Value); M = max(Len);
% 绘制环形柱状图网格
tt = linspace(pi/2, -pi/2, 100); xx = cos(tt); yy = sin(tt);
XX = repmat([xx.'; nan], [1, N]).*repmat(((1:N) + .5)./(N + .5), [101, 1]);
YY = repmat([yy.'; nan], [1, N]).*repmat(((1:N) + .5)./(N + .5), [101, 1]);
plot(XX(:), YY(:), 'LineWidth',1, 'Color',[1,1,1].*.9)
th = [pi/2, -pi/2, pi/6, -pi/6];
XX = [th.*0; cos(th); th.*nan];
YY = [th.*0; sin(th); th.*nan];
plot(XX(:), YY(:), 'LineWidth',1, 'Color',[1,1,1].*.9)
% 绘制柱状图
for i = 1:N
    R = (N - i + 1)./(N + .5); r = .3./(N + .5);
    TT = (tt - pi/2).*.8.*Len(i)./M + pi/2;
    XX = [cos(TT).*(R + r), cos(TT(end:-1:1)).*(R - r)];
    YY = [sin(TT).*(R + r), sin(TT(end:-1:1)).*(R - r)];
    fill(XX, YY, CList(Class(i),:), 'LineWidth',1.5)
    text(cos(TT(end)).*R + sin(TT(end))./(N)./2, sin(TT(end)).*R - cos(TT(end))./(N)./2, ...
        num2str(Value(i)), 'HorizontalAlignment','center', 'FontName','Arial', 'FontSize',13)
    text(-.05, R, Name{i}, 'HorizontalAlignment','right', 'FontName','Arial', 'FontSize',13)
end
for i = 1:max(Class)
    lgdHdl1(i) = fill([115,108,97,110,100], [97,114,101,114,32], CList(Class(i),:), 'LineWidth',1.5);
end
lgd1 = legend(lgdHdl1, ClassName, 'Box','off', 'FontName','Arial', ...
    'FontSize',16, 'FontWeight','bold', 'Location','northwest');
%% 核密度图

ax2 = axes('Parent',gcf, 'Position',[.18,.1,.42,.4], 'NextPlot','add', ...
    'XLim', [-20,100], 'LineWidth',1.5, 'Box','on', 'TickLength',[.001,0], ...
    'TickDir','out', 'FontSize',13);
xlabel(ax2, 'XXXX-XXXX-xxxxxxxx', 'FontName','Arial', 'FontSize',16)
ylabel(ax2, 'Density', 'FontName','Arial', 'FontSize',16)
xline(40, 'LineWidth',1, 'Alpha',1, 'LineStyle','--');

for i = 1:max(NumClass)
    x = Num(NumClass == i);
    [f, xi] = ksdensity(x);
    lgdHdl2(i) = area(xi, f, 'FaceColor',CList(i,:), 'EdgeColor',CList(i,:), 'FaceAlpha',.5);
    lgdtxt{i} = ['Mean counts: ' ,num2str(round(mean(x)))];
end
lgd2 = legend(lgdHdl2, lgdtxt, 'Box','off', 'FontName','Arial', ...
    'FontSize',16, 'Location','northeast');

完整代码可以从以下gitee仓库获取:

相关推荐
孤独的追光者3 小时前
MATLAB导出滤波器参数至ADSP中使用
算法·matlab
Coisinilove3 小时前
MATLAB微分方程求解
开发语言·matlab·微分方程
busideyang4 小时前
MATLAB vs Rust在嵌入式领域的角色定位
开发语言·matlab·rust
ghie90904 小时前
蚁群全局最优算法:原理、改进与MATLAB实现
开发语言·算法·matlab
沐风老师1 天前
【科研绘图】3DMAX血管神经生成器CapillaryGenerator插件使用方法详解
3dmax插件·3dmax·科研绘图·血管神经生成器·capillary
Highcharts.js1 天前
什么是哑铃图?如何使用Highcharts创建哑铃图表?
科研绘图·highcharts·图表开发·哑铃图·dumbbell chart·前后对比图·变化分析图表
dracula0003 天前
Simulink建模助手系列-7【根据From创建Bus Creator】
matlab
dracula0004 天前
Simulink建模助手系列-进阶2【解析Bus总线信号层次结构】
matlab
@陈小鱼4 天前
基于 Savitzky-Golay滤波器的超声图像运动分析方法
python·计算机视觉·matlab·信号处理