MATLAB | 全网唯一 ,MATLAB绘制阴影柱状图(填充斜线)

Posted slandarer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MATLAB | 全网唯一 ,MATLAB绘制阴影柱状图(填充斜线)相关的知识,希望对你有一定的参考价值。

阴影柱状图绘制的代码MATHWORKS上也有,不过是生成图片后,识别图像上不同颜色块并直接修改像素生成阴影线,这样的生成方式不可逆且自由度较低,因此本人开发了一个直接画线条填充的硬画版本。

另:由于不太想动脑子,使用polyshape对象进行了交点判定,减少了代码出错的概率,但由于代码开发基于polyshape对象,阴影柱状图绘制函数理论上需要至少R2017b及之后版本才能使用(越新越好)。

由于工具函数过长,将被放在最后展示,以下将先展示函数用法。

示例图


使用教程

1 基本使用

就短短三行代码就能画,真的简单:

y=[2 2 -3 -2 -5; -2 -5 6 2 5; 9 8 9 2 5];

SH=shadowHist(y,'ShadowType','/','\\','.','x','|');
SH=SH.draw();

2 添加图例

使用legend函数添加图例,使用方式如下:

y=[2 2 3 2 5; 2 5 6 2 5; 9 8 9 2 5];

SH=shadowHist(y,'ShadowType','/','\\','.','_','+');
SH=SH.draw();
SH=SH.legend('AAAAAAA','BBBBBBB','CCCCCCC','DDDDDDD','EEEEEEE','FontName','Arial','FontSize',11);

图例是自行绘制的,能拖动及自动缩放(老难算了这玩意):

3 阴影格式

阴影有:
\\,/,_,|,+,x,.,w,k,g
十种格式,以下全部展示一下:

y=[2 2 3 2 5 4 2 2 2 1;2 2 3 2 5 4 2 4 3 6];

SH=shadowHist(y,'ShadowType','/','\\','x','.','_','|','+','w','k','g');
SH=SH.draw();
SH=SH.legend('A','B','C','D','E','F','G','H','I','J');

4 特殊结构

含负数

y=[2 2 -3 -2 -5; -2 -5 6 2 5; 9 8 9 2 5];

SH=shadowHist(y,'ShadowType','/','\\','.','x','|');
SH=SH.draw();

堆叠柱状图

y=[2 2 -3 -2 -5; -2 -5 6 2 5; 9 8 9 2 5; -3 -5 6 2 5; 4 8 5 2 5];

SH=shadowHist(y,'ShadowType','/','\\','.','x','|','stacked');
SH=SH.draw();

5 额外修饰

阴影、柱状图框、图例框分别具有barShadow,barBox,lgdBox的标签,使用findobj获取对象并循环修饰即可,不过为了绘制更好看,部分阴影使用plot绘制部分则是使用scatter绘制,因此阴影修饰时要用if先检测一下格式,给个示例:

y=[2 2 3 2 5; 2 5 6 2 5; 9 8 9 2 5];

SH=shadowHist(y,'ShadowType','/','\\','.','_','+');
SH=SH.draw();
SH=SH.legend('AAAAAAA','BBBBBBB','CCCCCCC','DDDDDDD','EEEEEEE','FontName','Cambria','FontSize',11);

% 修饰阴影变成红色并加粗
shadowHdl=findobj('Tag','barShadow');
for i=1:length(shadowHdl)
    if isa(shadowHdl(i),'matlab.graphics.chart.primitive.Line')
        shadowHdl(i).Color=[.8,.6,.6];
        shadowHdl(i).LineWidth=1;
    else
        shadowHdl(i).MarkerFaceColor=[.8,.6,.6];
        shadowHdl(i).SizeData=5;
    end
end

% 修饰框变为蓝色并加粗
boxHdl=findobj('Tag','barBox');
for i=1:length(boxHdl)
    boxHdl(i).EdgeColor=[.3,.3,.8];
    boxHdl(i).LineWidth=2;
end

% 图例框加粗并变成绿色
lgdBox=findobj('Tag','lgdBox');
lgdBox.LineWidth=1.3;
lgdBox.EdgeColor=[.1,.3,.1];
lgdBox.FaceColor=[173,189,163]./255;

光看上面代码大佬们应该就已经懂了咋用,如果比较小白,可以直接使用MATLAB自带的属性修饰器:

点击:查看->属性修饰器

点击选中对象即可立即修饰颜色、粗细等各种格式:


工具函数完整代码

classdef shadowHist
% @author : slandarer
% gzh  : slandarer随笔

% 使用示例:
% =========================================================================
% y=[2 2 3 2 5; 2 5 6 2 5; 9 8 9 2 5];
% 
% SH=shadowHist(y,'ShadowType','/','\\','.','x','|');
% SH=SH.draw();

    properties
        ax         % 绘图坐标区域
        YData      % 数值矩阵
        shadowTypeList='\\','/','_','|','+','x','.','w','k','g'
        shadowType % 阴影类型
        otherProp  % 其他初始属性

        oriBarHdl  % 原始图形句柄
        newBarHdl
        pshapeHdl  % polyshape图形句柄
        groupNum   % 组数  
        classNum   % 类数
        YEndMat    % 末端y值
        maxY       % 最大Y值   
        minY=0     % 最小Y值
        diffY      % Y值之差
        BarW       % 宽度
        YSep1      % linspace(obj.minY,obj.maxY+.02.*obj.diffY,obj.lineNum)
        YSep2
        XMean      % 每组柱状图每个柱子的中心位置
        lineNum=90 % 阴影基础线数量

        XYRate
        SHLegend
        oriLegend
    end

    methods
        function obj=shadowHist(varargin)
            % 基础属性设置
            if isa(varargin1,'matlab.graphics.axis.Axes')
                obj.ax=varargin1;varargin(1)=[];
            else
                obj.ax=gca;
            end
            hold(obj.ax,'on');
            obj.YData=varargin1;varargin(1)=[];
            if any(strcmpi('shadowType',varargin))
                tind=find(strcmpi('shadowType',varargin));
                obj.shadowType=varargintind+1;
                varargin([tind,tind+1])=[];
            else
                obj.shadowType=obj.shadowTypeList;
            end
            obj.otherProp=varargin;
            help shadowHist
        end

        function obj=draw(obj)
            % 基础绘图
            obj.oriBarHdl=bar(obj.ax,obj.YData,obj.otherProp:,'Tag','barBox');
            obj.XYRate=diff(obj.ax.YLim)./diff(obj.ax.XLim);
            % 更多属性获取
            obj.YEndMat=zeros([length(obj.oriBarHdl),length(obj.oriBarHdl(1).XData)]);
            for i=1:length(obj.oriBarHdl)
                obj.YEndMat(i,:)=obj.oriBarHdl(i).YEndPoints;
            end
            obj.maxY=max(obj.YEndMat,[],[1,2]);
            obj.minY=min(0,min(obj.YEndMat,[],[1,2]));
            obj.diffY=obj.maxY-obj.minY;


            obj.classNum=length(obj.oriBarHdl);
            obj.groupNum=length(obj.oriBarHdl(1).XData);

            % 计算柱状图宽度和位置
            % obj.XMean=linspace(-obj.classNum+1,obj.classNum-1,obj.classNum)./(3+2*obj.classNum);
            for i=1:obj.classNum
                obj.XMean(i)=obj.oriBarHdl(i).XEndPoints(1)-1;
            end
            tXMean=[obj.XMean,1];obj.BarW=(tXMean(2)-tXMean(1))./2.*obj.oriBarHdl(1).BarWidth;
            if strcmp(obj.oriBarHdl(1).BarLayout,'stacked')
                obj.BarW=1./2.*obj.oriBarHdl(1).BarWidth;
            end
            YY1=linspace(obj.minY,obj.maxY+.02.*obj.diffY,obj.lineNum)';
            YY2=linspace(obj.minY-.02.*obj.diffY,obj.maxY,obj.lineNum)';
            obj.YSep1=YY1(1)-YY2(2);obj.YSep2=YY1(2)-YY1(1);

            % 循环绘制阴影
            for i=1:obj.classNum
                obj.oriBarHdl(i).FaceColor='none';
                obj.oriBarHdl(i).LineWidth=.8;
                if strcmp(obj.oriBarHdl(1).BarLayout,'stacked')
                    obj.oriBarHdl(i).LineWidth=.8;
                end
                tType=mod(i-1,length(obj.shadowType))+1;
                switch obj.shadowTypetType
                    case 'w',obj.oriBarHdl(i).FaceColor=[1,1,1];
                    case 'k',obj.oriBarHdl(i).FaceColor=[0,0,0];
                    case 'g',obj.oriBarHdl(i).FaceColor=[.5,.5,.5];
                end
                for j=1:obj.groupNum
                    tX=[-1,1,1,-1].*obj.BarW+obj.XMean(i)+j;
                    tY=[obj.oriBarHdl(i).YEndPoints(j)-obj.oriBarHdl(i).YData(j),...
                        obj.oriBarHdl(i).YEndPoints(j)-obj.oriBarHdl(i).YData(j),...
                        obj.oriBarHdl(i).YEndPoints(j),...
                        obj.oriBarHdl(i).YEndPoints(j)];    
                    tPolyPhape=polyshape(tX,tY);
                    switch obj.shadowTypetType
                        case '\\'
                            XX1=-1.2.*ones([obj.lineNum,1]).*obj.BarW+obj.XMean(i)+j;
                            XX2=1.2.*ones([obj.lineNum,1]).*obj.BarW+obj.XMean(i)+j;
                            YY1=linspace(obj.minY,obj.maxY+.02.*obj.diffY,obj.lineNum)';
                            YY2=linspace(obj.minY-.02.*obj.diffY,obj.maxY,obj.lineNum)';
                            tXX=zeros([3,obj.lineNum]);tYY=zeros([3,obj.lineNum]);
                            for k=1:obj.lineNum
                                [in,~]=intersect(tPolyPhape,[XX1(k),YY1(k);XX2(k),YY2(k)]);
                                if ~isempty(in)
                                    tXX(:,k)=[inMATLAB | 全网唯一,使用MATLAB绘制矩形树状图

MATLAB | 全网唯一,使用MATLAB绘制矩形树状图

MATLAB | 全网唯一,双变量及三变量映射图表的MATLAB绘制

MATLAB | 全网唯一,双变量及三变量映射图表的MATLAB绘制

MATLAB | 全网唯一,使用MATLAB绘制好看的韦恩图(venn)

MATLAB | 全网唯一,使用MATLAB绘制好看的韦恩图(venn)