|

点击上方蓝字和“好玩的MATLAB”一起快乐玩耍吧!
$ A0 }0 ]* x7 L. N! |1 }8 D4 t
uvhgyjbvxj36405194538.jpg
- n: M! R$ Y3 D! H2 S8 g; |好玩的matlab
t+ t' `& I- ~带你解锁不一样的matlab新玩法
$ P7 @* {3 }) g7 Q8 K# c" |/ z8 j) g, `& `, r
今天偶然看见"某号"推文关于绘制横向纵向的堆叠图,小编觉得很漂亮,但是不提供源码,接着发现要付费 300¥,哎!作为社会主义接班人,崇尚开源精神的小编,没有条件就创造条件,这么简单的图,那我就自己复现一个源码吧~,喜欢此推文的小伙伴们记得点赞+关注+分享!【尊重作者劳动成果,转载请注明推文链接和公众号名】
$ o6 S$ F+ \) Y2 l% \2 C( T; a4 v! V" d* w6 [2 L& p+ n
xliineu20sl6405194638.png
- g% b& U R" J- l( ~8 M
效果图( H! \; x( X$ w3 E' O o* n2 h5 T G
42v405lk33v6405194739.png
0 |4 S' ]) D% [
, h3 i( @- x3 r* m/ ]
txi0mq3exji6405194839.gif
1 N% O2 {1 h( r5 Y: y7 ?! ?. [8 J
3 q' y, j; O2 o$ c# b基本代码复现纵向图
6 T6 l( @ R2 A6 ~3 a! ?; v
bkbevquddlt6405194939.png
- s( ]( o, Q; c' O
% 清除命令行、清除工作空间和关闭所有图形clc; clear; close all;%--------------------------------------------------------------------------% @Author: 好玩的Matlab% @公众号:好玩的Matlab% @Created: 09,10,2023% @Email: 2377389590@qq.com% @【尊重作者劳动成果,转载请注明推文链接和公众号名】% @Disclaimer: This code is provided as-is without any warranty.%--------------------------------------------------------------------------% 定义各个柱状条的颜色colors = [ 0.656, 0.0280, 0.148; 0.964, 0.416, 0.264; 1.000, 0.864, 0.556; 0.928, 0.956, 0.936; 0.532, 0.736, 0.864; 0.224, 0.308, 0.600];% 定义正数部分数据posX = [1.90 1.70 1.30 0.9 0.6 0.4; 2.66 2.38 1.82 1.26 0.84 0.560; 3.80 3.40 2.60 1.80 1.20 0.8; 5.20 4.40 3.60 2.60 1.60 0.8; 6.80 5.40 4.60 3.40 2.20 1; 7.60 6.60 5.40 3.60 2.40 1.6; 8.20 6.80 5.40 4.20 2.40 3; 7.60 6.60 5.40 3.60 2.40 1.6; 6.80 5.40 4.60 3.40 2.20 1; 5.20 4.40 3.60 2.60 1.60 0.8; 3.80 3.40 2.60 1.80 1.20 0.8; 2.66 2.38 1.82 1.26 0.840 0.56; 1.90 1.70 1.30 0.9 0.6 0.4];% 定义负数部分数据(正数部分的-0.5倍)negX = posX * -0.5;% 获取数据的维度[rows, cols] = size(posX);% 创建图形figure;hold on;% 绘制正数部分的柱状图posB = bar(posX, 'stacked', 'EdgeColor', 'none');% 为每个正数柱状条设置颜色for i = 1:numel(posB) posB(i).FaceColor = colors(i, :);end% 绘制负数部分的柱状图negB = bar(negX, 'stacked', 'EdgeColor', 'none');% 为每个负数柱状条设置颜色for i = 1:numel(negB) negB(i).FaceColor = colors(i, :);end% 添加图例legName = {'demo1', 'demo2', 'demo3', 'demo4', 'demo5', 'demo6'};lg = legend(legName, 'Location', 'best', 'EdgeColor', [1, 1, 1] * 0.5);% 设置坐标轴标签tickNames = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'};defaultAxes('ver', tickNames);% 清除图例的最后一项(如果有需要)lg.String(end) = [];
2 I* C) g) h; a' e- I
rsbsvyfabqy6405195039.png
! X% s2 z8 j" [ M! d6 I n
?
% P2 A, J* x. |0 h1 M
+ U' {# P0 T! b基本代码复现横向图 @4 ?4 V: z( Z$ w3 j
, `! B8 {6 |1 m3 y
clc;clear;close all;%--------------------------------------------------------------------------% @Author: 好玩的Matlab% @公众号:好玩的Matlab% @Created: 09,10,2023% @Email:2377389590@qq.com% @【尊重作者劳动成果,转载请注明推文链接和公众号名】% @Disclaimer: This code is provided as-is without any warranty.%--------------------------------------------------------------------------- X1 C: a+ }7 J5 N% ]
% 颜色定义colors = hsv(6);% 定义数据posX = [1.90 1.70 1.30 0.9 0.6 0.4; 2.66 2.38 1.82 1.26 0.84 0.560; 3.80 3.40 2.60 1.80 1.20 0.8; 5.20 4.40 3.60 2.60 1.60 0.8; 6.80 5.40 4.60 3.40 2.20 1; 7.60 6.60 5.40 3.60 2.40 1.6; 8.20 6.80 5.40 4.20 2.40 3; 7.60 6.60 5.40 3.60 2.40 1.6; 6.80 5.40 4.60 3.40 2.20 1; 5.20 4.40 3.60 2.60 1.60 0.8; 3.80 3.40 2.60 1.80 1.20 0.8; 2.66 2.38 1.82 1.26 0.840 0.56; 1.90 1.70 1.30 0.9 0.6 0.4]; % 正数部分negX = -0.5 * posX; % 负数部分% 获取数据的维度[rows, cols] = size(posX);% 创建图形figure;hold on;% 画正数部分的条形图posB = barh(posX, 'stacked', 'EdgeColor', 'none');% 设置正数部分的颜色for i = 1:cols posB(i).FaceColor = colors(i, :);end% 画负数部分的条形图negB = barh(negX, 'stacked', 'EdgeColor', 'none');% 设置负数部分的颜色for i = 1:cols negB(i).FaceColor = colors(i, :);endlegName={'demo1', 'demo2','demo3','demo4','demo5','demo6'};lg=legend(legName,'Location','best','EdgeColor',[1,1,1]*0.5);tickNames={'A', 'B','C','D','E','F','G','H','I','J','K','L','M'};defaultAxes('hor',tickNames)lg.String(end) = [];) i) p" E3 P0 S( B Q2 m0 A7 H! x' U6 k
fcmqncyklj56405195139.png
, E1 |' |# G% o) |/ {% G3 S% d其中defaultAxes是图片修饰代码如下:function defaultAxes(type, tickNames)%--------------------------------------------------------------------------% @Author: 好玩的Matlab% @公众号:好玩的Matlab% @Created: 09,10,2023% @Email: 2377389590@qq.com% @【尊重作者劳动成果,转载请注明推文链接和公众号名】% @Disclaimer: This code is provided as-is without any warranty.%-------------------------------------------------------------------------- % 获取当前的坐标轴 ax = gca;" Z+ `4 K6 v$ U* y9 B! ]
% 基本坐标轴设置 ax.Box = 'off'; ax.Color = [1, 1, 1]; % 背景颜色设置为白色 ax.LineWidth = 1; % 坐标轴线宽度 ax.FontSize = 16; % 坐标轴字体大小 ax.FontName = 'Times New Roman'; % 设置字体类型
9 ^7 _6 _( y# R6 e* ? % 网格线设置 ax.GridLineStyle = '-'; % 主网格线样式 ax.GridColor = 'k'; % 主网格线颜色(黑色) ax.GridAlpha = 0.2; % 主网格线透明度 ax.MinorGridLineStyle = '-'; % 次网格线样式 ax.MinorGridColor = [0 0 0]; % 次网格线颜色(黑色) ax.MinorGridAlpha = 0.3; % 次网格线透明度. b' G2 b! q- `" r/ g
% 刻度设置 ax.XMinorTick = 'off'; % x轴次刻度关闭 ax.YMinorTick = 'off'; % y轴次刻度关闭 ax.TickDir = 'out'; % 刻度线方向向外1 i# K2 W/ S) C; d7 D6 r: U
% 调整坐标轴范围 ax.XLim = [min(ax.XLim) * 1.03, max(ax.XLim) * 1.03]; ax.YLim = [min(ax.YLim) * 1.03, max(ax.YLim) * 1.03];
( V4 A0 F4 w4 \* G % 根据图的类型(纵向或横向)进行不同设置 if strcmp(type, 'ver') ax.XGrid = 'off'; ax.YGrid = 'on'; ax.XTick = 1:length(tickNames); ax.XTickLabel = tickNames; line([xlim], [0 0], 'Color', 'k', 'LineWidth', 1); elseif strcmp(type, 'hor') ax.XGrid = 'on'; ax.YGrid = 'off'; ax.YTick = 1:length(tickNames); ax.YTickLabel = tickNames; line([0 0], [ylim], 'Color', 'k', 'LineWidth', 1); else error('Invalid orientation. Choose either "ver" or "hor".'); end/ i3 ~* {' e1 u$ F
% 添加额外的坐标轴(右侧和顶部) axur = axes('Units', ax.Units, ... 'Position', ax.Position, ... 'XAxisLocation', 'top', ... 'YAxisLocation', 'right', ... 'Color', 'none', ... 'XColor', ax.XColor, ... 'YColor', ax.YColor);
! `, f& r! Z7 a! b. @ axur.LineWidth = 1; axur.XTick = []; axur.YTick = [];end觉得这两种绘图方式还是不够简洁,于是我撸了一个绘制纵向和横向的堆叠图调用的类函数StackedBarPlotter。 F4 g5 r9 a, @
StackedBarPlotter类函数
3 ^' p. m/ B2 E/ \$ ?( |
4 O7 {, f- k4 ^0 |7 `classdef StackedBarPlotter %-------------------------------------------------------------------------- % @Author: 好玩的Matlab % @公众号:好玩的Matlab % @Created: 09,10,2023 % @Email:2377389590@qq.com % @【尊重作者劳动成果,转载请注明推文链接和公众号名】 % @Disclaimer: This code is provided as-is without any warranty. %--------------------------------------------------------------------------
1 B- e! M' ]. I' @* m& V1 a$ |- q, g properties PosX % 正数部分数据 NegX % 负数部分数据 Colors % 柱状图颜色 TickNames % 坐标轴标签名称 Type % 图的方向(纵向或横向) end
$ E) ]& K# K5 r1 R: ? methods % 构造函数 function obj = StackedBarPlotter(varargin) % 获取默认参数值 defValues = obj.getDefaultValues();6 {( H. j, S- C/ C( q) H; c
% 解析输入参数 p = obj.parseInput(defValues, varargin{:});( }. q, r: v# B' ~
% 从解析结果中设置对象属性 obj.PosX = p.Results.PosX; obj.NegX = p.Results.NegX; obj.Colors = p.Results.Colors; obj.TickNames = p.Results.TickNames; obj.Type = p.Results.Type; end0 E! z$ [* l. j1 P- }
% 绘图函数 function plot(obj) [rows, cols] = size(obj.PosX); hold on; if strcmp(obj.Type, 'ver') % 使用 bar 绘制纵向图 poxB = bar(obj.PosX, 'stacked', 'EdgeColor', 'none'); negB = bar(obj.NegX, 'stacked','EdgeColor','none'); elseif strcmp(obj.Type, 'hor') % 使用 barh 绘制横向图 poxB = barh(obj.PosX, 'stacked', 'EdgeColor', 'none'); negB = barh(obj.NegX, 'stacked','EdgeColor','none'); set(gca, 'YTick', 1:rows, 'YTickLabel', obj.TickNames); else error('Invalid orientation. Choose either "vertical" or "horizontal".'); end % 设置颜色 for i = 1:cols poxB(i).FaceColor = obj.Colors(i, :); negB(i).FaceColor = obj.Colors(i, :); end end end$ O J" q. Z2 q( ], U, i2 r$ z6 V
methods (Access = private) % 获取默认值的私有方法 function defValues = getDefaultValues(~) % 在这里定义默认值 defValues = struct('PosX', [], 'NegX', [], 'Colors', [], 'TickNames', {}, 'Type', 'ver'); end& Z2 q/ l9 ~) \$ N0 e+ H) C
% 解析输入参数的私有方法 function p = parseInput(~, defValues, varargin) p = inputParser; p.CaseSensitive = false; % 添加参数、默认值和验证函数 addParameter(p, 'PosX', defValues.PosX, @isnumeric); addParameter(p, 'NegX', defValues.NegX, @isnumeric); addParameter(p, 'Colors', defValues.Colors, @isnumeric); addParameter(p, 'TickNames', defValues.TickNames, @iscellstr); addParameter(p, 'Type', defValues.Type, @(x) any(validatestring(x, {'ver', 'hor'}))); % 解析输入参数 parse(p, varargin{:}); end endend这个Matlab类StackedBarPlotter是用于生成堆积柱状图的。具体地,它包括以下功能:属性(properties)PosX: 正数部分数据,用于绘制图中的正向柱。NegX: 负数部分数据,用于绘制图中的负向柱。Colors: 柱状图的颜色。TickNames: 坐标轴标签名称。Type: 图的方向,可以是纵向('ver')或横向('hor')。方法(methods)构造函数(Constructor): 当创建一个StackedBarPlotter对象时,这个构造函数会被调用。它接受多个参数,如PosX, NegX, Colors等,并设置这些作为对象属性。plot方法: 这个方法用于绘制图像。它根据Type属性(纵向或横向)来选择使用Matlab的bar函数还是barh函数。私有方法(methods with Access = private)getDefaultValues: 返回一个包含默认值的结构体。这些默认值用于初始化对象属性。parseInput: 这个方法用于解析传入构造函数的参数。它使用Matlab的inputParser来验证参数并设置它们。工作流程当你创建一个StackedBarPlotter对象时,构造函数会被调用,它会解析输入参数并设置对象的属性。之后,你可以调用plot方法来绘制堆积柱状图。
$ M y1 ~, X1 Y# {2 E调用方式
# o* ^- b3 H5 G4 ]5 E( ~: W- }( a) i+ |3 F3 j- Z. i; t, O
% 清除命令行、清除工作空间和关闭所有图形clc; clear; close all;0 J! G% L0 ?8 Y ~
%--------------------------------------------------------------------------% @Author: 好玩的Matlab% @公众号:好玩的Matlab% @Created: 09,10,2023% @Email: 2377389590@qq.com% @【尊重作者劳动成果,转载请注明推文链接和公众号名】% @Disclaimer: This code is provided as-is without any warranty.%--------------------------------------------------------------------------
: p" R1 ^9 Y& B% 定义正数部分数据和颜色5 Z* }, P# h. B8 N w; Z0 ]5 E
colors = jet(6);x=[linspace(-3,3,13)].^2;posX =[x;x*0.9;x*0.8;x*0.7;x*0.6;x*0.9]';negX = posX * -0.5; % 定义负数部分数据(正数部分的-0.5倍)% 定义坐标轴标签ticknames = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'};% 创建第一个图形(纵向)figure;subplot(1,2,1)plotterVer = StackedBarPlotter('posX', posX, 'negX', negX, 'colors', colors, 'TickNames', ticknames, 'type', 'ver');plotterVer.plot();% 添加图例legName = {'demo1', 'demo2', 'demo3', 'demo4', 'demo5', 'demo6'};lg = legend(legName, 'Location', 'best', 'EdgeColor', [1, 1, 1] * 0.5);defaultAxes('ver', ticknames);lg.String(end) = [];% s" ]1 b' |( g& `1 G
% 创建第二个图形(横向)subplot(1,2,2)colors = turbo(6);plotterHor = StackedBarPlotter('posX', posX, 'negX', negX, 'colors', colors, 'TickNames', ticknames, 'type', 'hor');plotterHor.plot();% 添加图例legName = {'demo1', 'demo2', 'demo3', 'demo4', 'demo5', 'demo6'};lg = legend(legName, 'Location', 'best', 'EdgeColor', [1, 1, 1] * 0.5);defaultAxes('hor', ticknames);lg.String(end) = [];
0 Q& B: M7 m7 o, L$ }4 f/ ~, E
l11nnraj1sj6405195240.png
- C T% S& W) i/ H' h
6 I! C: F1 _6 ]/ S- -THE END- -
* F j, U1 { }' G+ i& G+ I
1 U% R$ N h" }7 Y! F$ G源码下载:gitee下载:https://gitee.com/iDMatlab/StackedBarPlotter1 m- x! ^0 P$ `) s
zdbbkgbddh26405195340.png
" o6 p/ r, y+ Q4 q7 ~小编测试环境:Mac m1、MATLAB22b参考资料:
2 b1 ?' `9 i0 z# Z【1】颜色提取工具:https://c.runoob.com/front-end/6214/#d1e54e【2】https://www.mathworks.com/help/releases/R2021b/matlab/ref/bar.html【3】https://www.mathworks.com/help/releases/R2021b/matlab/ref/barh.html【4】https://mp.weixin.qq.com/s/isdAfipwwZeIjd-3wWS0Cw
) z, q2 J4 ~' I9 ^2 u& O9 j
) V8 ]9 g. Y8 P) B: w4 j5 Y. T+ ]扫一扫加QQ群/ _) Q: i: M1 {, [7 P
fhqay55o4uv6405195440.jpg
7 S% f$ y& S$ V
扫一扫加管理员微信% k$ e; ~$ Q! D/ o
gckox51mvm26405195540.png
R; {3 _% m2 r: Y6 | Y9 D9 k
euhy50jtihv6405195640.jpg
|
|