利用MATLAB绘制矩阵色块图和热图
MATLAB自带热图命令:
h = heatmap(XVarNames, XVarNames, R_t)
https://ww2.mathworks.cn/help/matlab/ref/heatmap.html
热图属性控制:
https://ww2.mathworks.cn/help/matlab/ref/matlab.graphics.chart.heatmapchart-properties.html
https://blog.csdn.net/qing101hua/article/details/92799912自己编写的矩阵色块图:
>> x = [1,-0.2,0.3,0.8,-0.5
-0.2,1,0.6,-0.7,0.2
0.3,0.6,1,0.5,-0.3
0.8,-0.7,0.5,1,0.7
-0.5,0.2,-0.3,0.7,1];
>> XVarNames = {\'xiezhh\',\'heping\',\'keda\',\'tust\',\'tianjin\'};
>> matrixplot(x,\'FillStyle\',\'nofill\',\'XVarNames\',XVarNames,\'YVarNames\',XVarNames);
根据矩阵元素值自动设置文字颜色:
>> matrixplot(x,\'FillStyle\',\'nofill\',\'XVarNames\',XVarNames,\'YVarNames\',XVarNames,\'TextColor\',\'Auto\',\'ColorBar\',\'on\');
【例2】绘制实值矩阵各元素对应的色块,通过不同的“参数/参数值”控制色块的形状、大小、颜色等属性。
方形色块,充满方格,灰白色字体
>> matrixplot(x,\'XVarNames\',XVarNames,\'YVarNames\',XVarNames,\'TextColor\',[0.6,0.6,0.6],\'ColorBar\',\'on\');
方形色块,根据矩阵元素值自动确定色块的大小和颜色,不显示字体
>> matrixplot(x,\'XVarNames\',XVarNames,\'YVarNames\',XVarNames,\'DisplayOpt\',\'off\',\'FigSize\',\'Auto\',\'ColorBar\',\'on\');
椭圆形色块,根据矩阵元素值自动确定色块的大小和颜色,不显示字体
>> matrixplot(x,\'XVarNames\',XVarNames,\'YVarNames\',XVarNames,\'DisplayOpt\',\'off\',\'FigSize\',\'Auto\',\'ColorBar\',\'on\',\'FigShape\',\'e\');
圆形色块,根据矩阵元素值自动确定色块的大小和颜色,不显示字体,上三角形式显示
>> matrixplot(x,\'XVarNames\',XVarNames,\'YVarNames\',XVarNames,\'DisplayOpt\',\'off\',\'FigSize\',\'Auto\',\'ColorBar\',\'on\',\'FigShape\',\'c\',\'FigStyle\',\'Triu\');
六边形色块,根据矩阵元素值自动确定色块的大小和颜色,显示字体,下三角形式显示
>> matrixplot(x,\'XVarNames\',XVarNames,\'YVarNames\',XVarNames,\'DisplayOpt\',\'on\',\'FigSize\',\'Auto\',\'ColorBar\',\'on\',\'FigShape\',\'h\',\'FigStyle\',\'Tril\');
表盘形色块,根据矩阵元素值自动确定色块的颜色,不显示字体
>> matrixplot(x,\'XVarNames\',XVarNames,\'YVarNames\',XVarNames,\'DisplayOpt\',\'off\',\'FigSize\',\'Full\',\'ColorBar\',\'on\',\'FigShape\',\'d\');
【例3】读取真彩图片,绘制伪红外图。
>> I = double(imread(\'kids.tif\'));
>> matrixplot(I,\'DisplayOpt\',\'off\',\'colorbar\',\'on\',\'grid\',\'off\');
function matrixplot(data,varargin) % 根据实值矩阵绘制色块图,用丰富的颜色和形状形象的展示矩阵元素值的大小。 % % matrixplot(data) 绘制矩阵色块图,data为实值矩阵,每一个元素对应一个色块,色 % 块颜色由元素值大小决定。 % % matrixplot(data, \'PARAM1\',val1, \'PARAM2\',val2, ...) % 用成对出现的参数名/参数值控制色块的各项属性。可用的参数名/参数值如下: % \'FigShape\' --- 设定色块的形状,其参数值为: % \'Square\' --- 方形(默认) % \'Circle\' --- 圆形 % \'Ellipse\' --- 椭圆形 % \'Hexagon\' --- 六边形 % \'Dial\' --- 表盘形 % % \'FigSize\' --- 设定色块的大小,其参数值为: % \'Full\' --- 最大色块(默认) % \'Auto\' --- 根据矩阵元素值自动确定色块大小 % % \'FigStyle\' --- 设定矩阵图样式,其参数值为: % \'Auto\' --- 矩形矩阵图(默认) % \'Tril\' --- 下三角矩阵图 % \'Triu\' --- 上三角矩阵图 % % \'FillStyle\' --- 设定色块填充样式,其参数值为: % \'Fill\' --- 填充色块内部(默认) % \'NoFill\' --- 不填充色块内部 % % \'DisplayOpt\' --- 设定是否在色块中显示矩阵元素值,其参数值为: % \'On\' --- 显示矩阵元素值(默认) % \'Off\' --- 不显示矩阵元素值 % % \'TextColor\' --- 设定文字的颜色,其参数值为: % 表示单色的字符(\'r\',\'g\',\'b\',\'y\',\'m\',\'c\',\'w\',\'k\'),默认为黑色 % 1行3列的红、绿、蓝三元色灰度值向量([r,g,b]) % \'Auto\' --- 根据矩阵元素值自动确定文字颜色 % % \'XVarNames\' --- 设定X轴方向需要显示的变量名(默认为X1,X2,...),其参数值为: % 字符串矩阵或字符串元胞数组,若为字符串矩阵,其行数应与data的列数相同 % 若为字符串元胞数组,其长度应与data的列数相同。 % % \'YVarNames\' --- 设定Y轴方向需要显示的变量名(默认为Y1,Y2,...),其参数值为: % 字符串矩阵或字符串元胞数组,若为字符串矩阵,其行数应与data的行数相同 % 若为字符串元胞数组,其长度应与data的行数相同。 % % \'ColorBar\' --- 设定是否显示颜色条,其参数值为: % \'On\' --- 显示颜色条 % \'Off\' --- 不显示颜色条(默认) % % \'Grid\' --- 设定是否显示网格线,其参数值为: % \'On\' --- 显示网格线(默认) % \'Off\' --- 不显示网格线 % % Example: % x = [1,-0.2,0.3,0.8,-0.5 % -0.2,1,0.6,-0.7,0.2 % 0.3,0.6,1,0.5,-0.3 % 0.8,-0.7,0.5,1,0.7 % -0.5,0.2,-0.3,0.7,1]; % matrixplot(x); % matrixplot(x,\'DisplayOpt\',\'off\'); % matrixplot(x,\'FillStyle\',\'nofill\',\'TextColor\',\'Auto\'); % matrixplot(x,\'TextColor\',[0.7,0.7,0.7],\'FigShap\',\'s\',\'FigSize\',\'Auto\',\'ColorBar\',\'on\'); % matrixplot(x,\'TextColor\',\'k\',\'FigShap\',\'d\',\'FigSize\',\'Full\',\'ColorBar\',\'on\',\'FigStyle\',\'Triu\'); % XVarNames = {\'xiezhh\',\'heping\',\'keda\',\'tust\',\'tianjin\'}; % matrixplot(x,\'FigShap\',\'e\',\'FigSize\',\'Auto\',\'ColorBar\',\'on\',\'XVarNames\',XVarNames,\'YVarNames\',XVarNames); % % CopyRight:xiezhh(谢中华),2013.01.24编写 % 对第一个输入参数类型进行判断 if ~ismatrix(data) || ~isreal(data) error(\'输入参数类型不匹配:第一个输入参数应为实值矩阵\'); end % 解析成对出现的参数名/参数值 [FigShape,FigSize,FigStyle,FillStyle,DisplayOpt,TextColor,XVarNames,... YVarNames,ColorBar,GridOpt] = parseInputs(varargin{:}); % 产生网格数据 [m,n] = size(data); [x,y] = meshgrid(0:n,0:m); data = data(:); maxdata = nanmax(data); mindata = nanmin(data); rangedata = maxdata - mindata; if isnan(rangedata) warning(\'MATLAB:warning1\',\'请检查您输入的矩阵是否合适!\'); return; end z = zeros(size(x))+0.2; sx = x(1:end-1,1:end-1)+0.5; sy = y(1:end-1,1:end-1)+0.5; if strncmpi(FigStyle,\'Tril\',4) z(triu(ones(size(z)),2)>0) = NaN; sx(triu(ones(size(sx)),1)>0) = NaN; elseif strncmpi(FigStyle,\'Triu\',4) z(tril(ones(size(z)),-2)>0) = NaN; sx(tril(ones(size(sx)),-1)>0) = NaN; end sx = sx(:); sy = sy(:); id = isnan(sx) | isnan(data); sx(id) = []; sy(id) = []; data(id) = []; if isempty(XVarNames) XVarNames = strcat(\'X\',cellstr(num2str((1:n)\'))); else if (iscell(XVarNames) && (numel(XVarNames) ~= n)) || (~iscell(XVarNames) && (size(XVarNames,1) ~= n)) error(\'X轴方向变量名应为字符串矩阵或字符串元胞数组,其长度与输入矩阵的列数相同\'); end end if isempty(YVarNames) YVarNames = strcat(\'Y\',cellstr(num2str((1:m)\'))); else if (iscell(YVarNames) && (numel(YVarNames) ~= m)) || (~iscell(YVarNames) && (size(YVarNames,1) ~= m)) error(\'Y轴方向变量名应为字符串矩阵或字符串元胞数组,其长度与输入矩阵的行数相同\'); end end % 绘图 figure(\'color\',\'w\',... \'units\',\'normalized\',... \'pos\',[0.289165,0.154948,0.409956,0.68099]); axes(\'units\',\'normalized\',\'pos\',[0.1,0.022,0.89,0.85]); if strncmpi(GridOpt,\'On\',2) mesh(x,y,z,... \'EdgeColor\',[0.7,0.7,0.7],... \'FaceAlpha\',0,... \'LineWidth\',1); % 参考网格线 end hold on; axis equal; axis([-0.1,n+0.1,-0.1,m+0.1,-0.5,0.5]); view(2); % 设置X轴和Y轴刻度位置及标签 set(gca,\'Xtick\',(1:n)-0.5,... \'XtickLabel\',XVarNames,... \'Ytick\',(1:m)-0.5,... \'YtickLabel\',YVarNames,... \'XAxisLocation\',\'top\',... \'YDir\',\'reverse\',... \'Xcolor\',[0.7,0.7,0.7],... \'Ycolor\',[0.7,0.7,0.7],... \'TickLength\',[0,0]); axis off % 绘制填充色块 if strncmpi(FillStyle,\'Fill\',3) MyPatch(sx\',sy\',data\',FigShape,FigSize); end % 显示数值文本信息 if strncmpi(DisplayOpt,\'On\',2) str = num2str(data,\'%4.2f\'); scale = 0.1*max(n/m,1)/(max(m,n)^0.55); if strncmpi(TextColor,\'Auto\',3) ColorMat = get(gcf,\'ColorMap\'); nc = size(ColorMat,1); cid = fix(mapminmax(data\',0,1)*nc)+1; cid(cid<1) = 1; cid(cid>nc) = nc; TextColor = ColorMat(cid,:); for i = 1:numel(data) text(sx(i),sy(i),0.1,str(i,:),... \'FontUnits\',\'normalized\',... \'FontSize\',scale,... \'fontweight\',\'bold\',... \'HorizontalAlignment\',\'center\',... \'Color\',TextColor(i,:)); end else text(sx,sy,0.1*ones(size(sx)),str,... \'FontUnits\',\'normalized\',... \'FontSize\',scale,... \'fontweight\',\'bold\',... \'HorizontalAlignment\',\'center\',... \'Color\',TextColor); end end % 设置X轴和Y轴刻度标签的缩进方式 MyTickLabel(gca,FigStyle); % 添加颜色条 if strncmpi(ColorBar,\'On\',2) if any(strncmpi(FigStyle,{\'Auto\',\'Triu\'},4)) colorbar(\'Location\',\'EastOutside\'); else colorbar(\'Location\',\'SouthOutside\'); end end end % --------------------------------------------------- % 调整坐标轴刻度标签子函数 % --------------------------------------------------- function MyTickLabel(ha,tag) % 根据显示范围自动调整坐标轴刻度标签的函数 % ha 坐标系句柄值 % tag 调整坐标轴刻度标签的标识字符串,可用取值如下: % \'Auto\' --- 将x轴刻度标签旋转90度,y轴刻度标签不作调整 % \'Tril\' --- 将x轴刻度标签旋转90度,并依次缩进,y轴刻度标签不作调整 % \'Triu\' --- 将x轴刻度标签旋转90度,y轴刻度标签依次缩进 % Example: % MyTickLabel(gca,\'Tril\'); % % CopyRight:xiezhh(谢中华),2013.1编写 if ~ishandle(ha) warning(\'MATLAB:warning2\',\'第一个输入参数应为坐标系句柄\'); return; end if ~strcmpi(get(ha,\'type\'),\'axes\') warning(\'MATLAB:warning3\',\'第一个输入参数应为坐标系句柄\'); return; end axes(ha); xstr = get(ha,\'XTickLabel\'); xtick = get(ha,\'XTick\'); xl = xlim(ha); ystr = get(ha,\'YTickLabel\'); ytick = get(ha,\'YTick\'); yl = ylim(ha); set(ha,\'XTickLabel\',[],\'YTickLabel\',[]); x = zeros(size(ytick)) + xl(1) - range(xl)/30; y = zeros(size(xtick)) + yl(1) - range(yl)/70; nx = numel(xtick); ny = numel(ytick); if strncmpi(tag,\'Tril\',4) y = y + (1:nx) - 1; elseif strncmpi(tag,\'Triu\',4) x = x + (1:ny) - 1; end text(xtick,y,xstr,... \'rotation\',90,... \'Interpreter\',\'none\',... \'color\',\'r\',... \'HorizontalAlignment\',\'left\'); text(x,ytick,ystr,... \'Interpreter\',\'none\',... \'color\',\'r\',... \'HorizontalAlignment\',\'right\'); end % --------------------------------------------------- % 根据散点数据绘制3维色块图子函数 % --------------------------------------------------- function MyPatch(x,y,z,FigShape,FigSize) % 根据散点数据绘制3维色块图 % MyPatch(x,y,z,FigShape,FigSize) x,y,z是实值数组,用来指定色块中心点三维 % 坐标。FigShape是字符串变量,用来指定色块形状。 % FigSize是字符串变量,用来指定色块大小。 % % CopyRight:xiezhh(谢中华), 2013.01 编写 % % Example: % x = rand(10,1); % y = rand(10,1); % z = rand(10,1); % MyPatch(x,y,z,\'s\',\'Auto\'); % % 输入参数类型判断 if nargin < 3 error(\'至少需要三个输入参数\'); end if ~isreal(x) || ~isreal(y) || ~isreal(z) error(\'前三个输入应为实值数组\'); end n = numel(z); if numel(x) ~= n || numel(y) ~= n error(\'坐标应等长\'); end if strncmpi(FigSize,\'Auto\',3) && ~strncmpi(FigShape,\'Ellipse\',1) id = (z == 0); x(id) = []; y(id) = []; z(id) = []; end if isempty(z) return; end % 求色块顶点坐标 rab1 = ones(size(z)); maxz = max(abs(z)); if maxz == 0 maxz = 1; end rab2 = abs(z)/maxz; if strncmpi(FigShape,\'Square\',1) % 方形 if strncmpi(FigSize,\'Full\',3) r = rab1; else r = sqrt(rab2); end SquareVertices(x,y,z,r); elseif strncmpi(FigShape,\'Circle\',1) % 圆形 if strncmpi(FigSize,\'Full\',3) r = 0.5*rab1; else r = 0.5*sqrt(rab2); end CircleVertices(x,y,z,r); elseif strncmpi(FigShape,\'Ellipse\',1) % 椭圆形 a = 0.48 + rab2*(0.57-0.48); b = (1-rab2).*a; EllipseVertices(x,y,z,a,b); elseif strncmpi(FigShape,\'Hexagon\',1) % 六边形 if strncmpi(FigSize,\'Full\',3) r = 0.5*rab1; else r = 0.5*sqrt(rab2); end HexagonVertices(x,y,z,r); else % 表盘形 if strncmpi(FigSize,\'Full\',3) r = 0.45*rab1; else r = 0.45*sqrt(rab2); end DialVertices(x,y,z,r); end end %-------------------------------------------------- % 求色块顶点坐标并绘制色块的子函数 %-------------------------------------------------- function SquareVertices(x,y,z,r) % 方形 hx = r/2; hy = hx; Xp = [x-hx;x-hx;x+hx;x+hx;x-hx]; Yp = [y-hy;y+hy;y+hy;y-hy;y-hy]; Zp = repmat(z,[5,1]); patch(Xp,Yp,Zp,\'FaceColor\',\'flat\',\'EdgeColor\',\'flat\'); end function CircleVertices(x,y,z,r) % 圆形 t = linspace(0,2*pi,30)\'; m = numel(t); Xp = repmat(x,[m,1])+cos(t)*r; Yp = repmat(y,[m,1])+sin(t)*r; Zp = repmat(z,[m,1]); patch(Xp,Yp,Zp,\'FaceColor\',\'flat\',\'EdgeColor\',\'flat\'); end function EllipseVertices(x,y,z,a,b) % 椭圆形 t = linspace(0,2*pi,30)\'; m = numel(t); t0 = -sign(z)*pi/4; t0 = repmat(t0,[m,1]); x0 = cos(t)*a; y0 = sin(t)*b; Xp = repmat(x,[m,1]) + x0.*cos(t0) - y0.*sin(t0); Yp = repmat(y,[m,1]) + x0.*sin(t0) + y0.*cos(t0); Zp = repmat(z,[m,1]); patch(Xp,Yp,Zp,\'FaceColor\',\'flat\',\'EdgeColor\',\'flat\'); end function HexagonVertices(x,y,z,r) % 六边形 t = linspace(0,2*pi,7)\'; m = numel(t); Xp = repmat(x,[m,1])+cos(t)*r; Yp = repmat(y,[m,1])+sin(t)*r; Zp = repmat(z,[m,1]); patch(Xp,Yp,Zp,\'FaceColor\',\'flat\',\'EdgeColor\',\'flat\'); end function DialVertices(x,y,z,r) % 表盘形 % 绘制表盘扇形 maxz = max(abs(z)); t0 = z*2*pi/maxz-pi/2; t0 = cell2mat(arrayfun(@(x)linspace(-pi/2,x,30)\',t0,\'UniformOutput\',0)); m = size(t0,1); r0 = repmat(r,[m,1]); Xp = [x;repmat(x,[m,1]) + r0.*cos(t0);x]; Yp = [y;repmat(y,[m,1]) + r0.*sin(t0);y]; Zp = repmat(z,[m+2,1]); patch(Xp,Yp,Zp,\'FaceColor\',\'flat\',\'EdgeColor\',[0,0,0]); % 绘制表盘圆周 t = linspace(0,2*pi,30)\'; m = numel(t); Xp = repmat(x,[m,1])+cos(t)*r; Yp = repmat(y,[m,1])+sin(t)*r; Zp = repmat(z,[m,1]); Xp = [Xp;flipud(Xp)]; Yp = [Yp;flipud(Yp)]; Zp = [Zp;flipud(Zp)]; patch(Xp,Yp,Zp,\'FaceColor\',\'flat\',\'EdgeColor\',[0,0,0]); end %-------------------------------------------------------------------------- % 解析输入参数子函数1 %-------------------------------------------------------------------------- function [FigShape,FigSize,FigStyle,FillStyle,DisplayOpt,TextColor,... XVarNames,YVarNames,ColorBar,GridOpt] = parseInputs(varargin) if mod(nargin,2)~=0 error(\'输入参数个数不对,应为成对出现\'); end pnames = {\'FigShape\',\'FigSize\',\'FigStyle\',\'FillStyle\',\'DisplayOpt\',... \'TextColor\',\'XVarNames\',\'YVarNames\',\'ColorBar\',\'Grid\'}; dflts = {\'Square\',\'Full\',\'Auto\',\'Fill\',\'On\',\'k\',\'\',\'\',\'Off\',\'On\'}; [FigShape,FigSize,FigStyle,FillStyle,DisplayOpt,TextColor,XVarNames,... YVarNames,ColorBar,GridOpt] = parseArgs(pnames, dflts, varargin{:}); validateattributes(FigShape,{\'char\'},{\'nonempty\'},mfilename,\'FigShape\'); validateattributes(FigSize,{\'char\'},{\'nonempty\'},mfilename,\'FigSize\'); validateattributes(FigStyle,{\'char\'},{\'nonempty\'},mfilename,\'FigStyle\'); validateattributes(FillStyle,{\'char\'},{\'nonempty\'},mfilename,\'FillStyle\'); validateattributes(DisplayOpt,{\'char\'},{\'nonempty\'},mfilename,\'DisplayOpt\'); validateattributes(TextColor,{\'char\',\'numeric\'},{\'nonempty\'},mfilename,\'TextColor\'); validateattributes(XVarNames,{\'char\',\'cell\'},{},mfilename,\'XVarNames\'); validateattributes(YVarNames,{\'char\',\'cell\'},{},mfilename,\'YVarNames\'); validateattributes(ColorBar,{\'char\'},{\'nonempty\'},mfilename,\'ColorBar\'); validateattributes(GridOpt,{\'char\'},{\'nonempty\'},mfilename,\'Grid\'); if ~any(strncmpi(FigShape,{\'Square\',\'Circle\',\'Ellipse\',\'Hexagon\',\'Dial\'},1)) error(\'形状参数只能为Square, Circle, Ellipse, Hexagon, Dial 之一\'); end if ~any(strncmpi(FigSize,{\'Full\',\'Auto\'},3)) error(\'图形大小参数只能为Full, Auto 之一\'); end if ~any(strncmpi(FigStyle,{\'Auto\',\'Tril\',\'Triu\'},4)) error(\'图形样式参数只能为Auto, Tril, Triu 之一\'); end if ~any(strncmpi(FillStyle,{\'Fill\',\'NoFill\'},3)) error(\'图形填充样式参数只能为Fill, NoFill 之一\'); end if ~any(strncmpi(DisplayOpt,{\'On\',\'Off\'},2)) error(\'显示数值参数只能为On,Off 之一\'); end if ~any(strncmpi(ColorBar,{\'On\',\'Off\'},2)) error(\'显示颜色条参数只能为On,Off 之一\'); end if ~any(strncmpi(GridOpt,{\'On\',\'Off\'},2)) error(\'显示网格参数只能为On,Off 之一\'); end end %-------------------------------------------------------------------------- % 解析输入参数子函数2 %-------------------------------------------------------------------------- function [varargout] = parseArgs(pnames,dflts,varargin) % Copyright 2010-2011 The MathWorks, Inc. % $Revision: 1.1.6.2 $ $Date: 2011/05/09 01:27:26 $ % Initialize some variables nparams = length(pnames); varargout = dflts; setflag = false(1,nparams); unrecog = {}; nargs = length(varargin); dosetflag = nargout>nparams; dounrecog = nargout>(nparams+1); % Must have name/value pairs if mod(nargs,2)~=0 m = message(\'stats:internal:parseArgs:WrongNumberArgs\'); throwAsCaller(MException(m.Identifier, \'%s\', getString(m))); end % Process name/value pairs for j=1:2:nargs pname = varargin{j}; if ~ischar(pname) m = message(\'stats:internal:parseArgs:IllegalParamName\'); throwAsCaller(MException(m.Identifier, \'%s\', getString(m))); end mask = strncmpi(pname,pnames,length(pname)); % look for partial match if ~any(mask) if dounrecog % if they\'ve asked to get back unrecognized names/values, add this % one to the list unrecog((end+1):(end+2)) = {varargin{j} varargin{j+1}}; continue else % otherwise, it\'s an error m = message(\'stats:internal:parseArgs:BadParamName\',pname); throwAsCaller(MException(m.Identifier, \'%s\', getString(m))); end elseif sum(mask)>1 mask = strcmpi(pname,pnames); % use exact match to resolve ambiguity if sum(mask)~=1 m = message(\'stats:internal:parseArgs:AmbiguousParamName\',pname); throwAsCaller(MException(m.Identifier, \'%s\', getString(m))); end end varargout{mask} = varargin{j+1}; setflag(mask) = true; end % Return extra stuff if requested if dosetflag varargout{nparams+1} = setflag; if dounrecog varargout{nparams+2} = unrecog; end end end
请发表评论