电子产业一站式赋能平台

PCB联盟网

搜索
查看: 238|回复: 0
收起左侧

MATLAB|怎么绘制横向和纵向堆叠图

[复制链接]

260

主题

260

帖子

1829

积分

三级会员

Rank: 3Rank: 3

积分
1829
发表于 2023-9-11 08:31:00 | 显示全部楼层 |阅读模式
点击上方蓝字和“好玩的MATLAB”一起快乐玩耍吧!
$ A0 }0 ]* x7 L. N! |1 }8 D4 t

uvhgyjbvxj36405194538.jpg

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

xliineu20sl6405194638.png
- g% b& U  R" J- l( ~8 M
效果图( H! \; x( X$ w3 E' O  o* n2 h5 T  G

42v405lk33v6405194739.png

42v405lk33v6405194739.png
0 |4 S' ]) D% [

, h3 i( @- x3 r* m/ ]

txi0mq3exji6405194839.gif

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

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

    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

    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

    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

    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

    fhqay55o4uv6405195440.jpg
    7 S% f$ y& S$ V
    扫一扫加管理员微信% k$ e; ~$ Q! D/ o

    gckox51mvm26405195540.png

    gckox51mvm26405195540.png
      R; {3 _% m2 r: Y6 |  Y9 D9 k

    euhy50jtihv6405195640.jpg

    euhy50jtihv6405195640.jpg
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表