全网唯一,MATLAB绘制各类螺旋图,还在为X轴过长而困扰吗?把X轴盘起来就可以优雅的绘图!!今天带来的是由本人开发的SSpiral MATLAB 工具包,,本期工具函数绘图效果:
工具函数放在最后,先看基本用法:
使用教程
1 坐标区域创建
使用SSpiral(gca)
的形式创建坐标区域,通过obj.set()
函数设置各种属性:
matlab">% Create spiral-axes
SS = SSpiral(gca);
设置螺旋角度范围:
matlab">% Set theta limit
SS.set('TLim',[0,3*360]) SS.set('TLim',[120,3*360])
设置X轴Y轴范围:
matlab">% Set X-axis limit and Y-axis limit
SS.set('XLim',[0,120], 'YLim',[0,10])
自定义刻度:
matlab">SS.set('XTick',0:5:120)
调整刻度线长度:
matlab">% Set ticks and minor-ticks length
SS.set('TickLength',[.2,.15])
隐藏次刻度线:
matlab">SS.set('XMinorTick','off')
2 柱状图绘制
多次使用obj.bar()
函数,画好多组柱状图:
matlab">figure('Units','normalized', 'Position',[.1,.1,.6,.75])% Create spiral-axes
SS1 = SSpiral(gca);
SS1.set('TLim',[0,2*360+180], 'XLim',[0,200]+.5, 'YLim',[0,1], 'XTick',0:5:200) X = rand(1,200);
SS1.bar(X);
SS1.bar(X./2);
SS1.bar(X./4);legend({'AAA','BBB'}, 'FontSize',12, 'FontName','Times New Roman')
画一组柱状图但是正负数不同颜色:
matlab">figure('Units','normalized', 'Position',[.1,.1,.6,.75])% Create spiral-axes
SS2 = SSpiral(gca);
SS2.set('TLim',[0,2*360+180], 'XLim',[0,200]+.5, 'YLim',[-.5,.5], 'XTick',0:5:200) X = rand(1,200) - .5;
X1 = X.*(X>0);
X2 = X.*(X<0);
SS2.bar(X1);
SS2.bar(X2);legend({'AAA','BBB'}, 'FontSize',12, 'FontName','Times New Roman')
3 标签及背景色
matlab">figure('Units','normalized', 'Position',[.1,.1,.6,.75])
% Create spiral-axes
SS2 = SSpiral(gca);
SS2.set('TLim',[0,2*360+180], 'XLim',[0,200]+.5, 'YLim',[0,1], 'XTick',0:5:200) % Set background color to light-blue
SS2.set('BackgroundColor',[228,243,245]./255)X = rand(1,200);
SS2.bar(X, 'FaceColor',[253,193,202]./255, 'EdgeColor','w');% Set tick-labels font
SS2.set('TickLabelFont', {'FontSize',10, 'FontName','Times New Roman', 'Color',[0,0,.5]})
4 堆叠柱状图
很简单就是输入多列的数据:
matlab">figure('Units','normalized', 'Position',[.1,.1,.6,.75])% Create spiral-axes
SS1 = SSpiral(gca);
SS1.set('TLim',[0,2*360+180], 'XLim',[0,200]+.5, 'YLim',[0,2], 'XTick',0:5:200) X = rand(200,2);
SS1.bar(X, 'FaceColor',[0.46,0.67,0.18; 0.30,0.74,0.93]);
legend({'AAA','BBB'}, 'FontSize',12, 'FontName','Times New Roman')% =========================================================================
figure('Units','normalized', 'Position',[.1,.1,.6,.75])% Create spiral-axes
SS2 = SSpiral(gca);
SS2.set('TLim',[0,2*360+180], 'XLim',[0,200]+.5, 'YLim',[-1,1], 'XTick',0:5:200) X = rand(200,2)-.5;
SS2.bar(X, 'FaceColor',[0.46,0.67,0.18; 0.30,0.74,0.93]);
legend({'AAA','BBB'}, 'FontSize',12, 'FontName','Times New Roman')
5 面积图
基础绘制:
matlab">% area diagram on spiral-axes
figure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS1 = SSpiral(gca);
SS1.set('TLim',[0,2*360+180], 'XLim',[1,200], 'YLim',[0,1], 'XTick',0:5:200)
Y = rand(200,1);
SS1.area(1:200,Y);% =========================================================================
% area diagrams on spiral-axes
figure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS2 = SSpiral(gca);
SS2.set('TLim',[0,2*360+180], 'XLim',[1,200], 'YLim',[0,1], 'XTick',0:5:200)
Y = rand(200,2);
SS2.area(1:200,Y(:,1));
SS2.area(1:200,Y(:,2));
正负数部分不同颜色:
matlab">% Different colors in the positive and negative parts
figure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS3 = SSpiral(gca);
SS3.set('TLim',[0,2*360+180], 'XLim',[1,200], 'YLim',[-.5,.5], 'XTick',0:5:200)
Y = rand(200,1)-.5;
Y = interp1(1:200, Y ,(1:.1:200).');
SS3.area(1:.1:200,Y.*(Y>0));
SS3.area(1:.1:200,Y.*(Y<0));
堆叠面积图:
matlab">% 堆叠面积图
% stacked-area diagram
figure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS4 = SSpiral(gca);
SS4.set('TLim',[0,2*360+180], 'XLim',[1,200], 'YLim',[0,1.8], 'XTick',0:5:200)
Y = rand(200,2);
SS4.area(1:200,Y);
legend({'AAA','BBB'}, 'FontSize',12, 'FontName','Times New Roman')
含负数堆叠面积图:
matlab">% 含有负数的堆叠面积图
% Containing negative numbers stacked-area diagram
figure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS5 = SSpiral(gca);
SS5.set('TLim',[0,2*360+180], 'XLim',[1,200], 'YLim',[-1,1], 'XTick',0:5:200)
Y = rand(200,2)-.5;
Y = interp1(1:200, Y ,1:.1:200);
SS5.area(1:.1:200,Y);
6 折线图与标签格式
通过设置TickLabelFormat
属性来设置标签格式,应该输入一个将数值转化为字符串的函数,通过XTickLabel
,YTickLabel
设置标签文本:
matlab">figure('Units','normalized', 'Position',[.1,.1,.6,.75])SS = SSpiral(gca);
SS.set('TLim',[0,3*360], 'XLim',[0,240], 'YLim',[0,1], 'XTick',0:20/3:240) Y = rand(121,2);
SS.plot(repmat((0:2:240)',[1,2]),Y, 'LineWidth',1, 'Marker', 'o');pause(1)
% 修改标签格式为最简分数
% Change the label format to the simplest fraction
SS.set('TickLabelFormat',@(x) strtrim(rats(x)))pause(1)
% 修改标签格式为指定字符串
strCell = [num2cell(char(32*ones(1,25))),{'January','February','March','April','May','June','July','August','September','October','November','December'}];
SS.set('XTickLabel',strCell)
SS.set('TickLabelFont',{'FontSize',14, 'FontName','Times New Roman'})
7 散点图
matlab">figure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS = SSpiral(gca);
SS.set('TLim',[0,2*360+180], 'XLim',[1,200], 'YLim',[0,1], 'XTick',0:5:200) Y = rand(1,100);
SS.scatter(1:2:200,Y,'filled', 'CData',[129,170,174]./255, 'Marker','o');
8 高亮区域
使用obj.xregion(lim)
和obj.yregion(lim)
函数:
matlab">figure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS = SSpiral(gca);
SS.set('TLim',[0,2*360+180], 'XLim',[1,200], 'YLim',[0,1], 'XTick',0:5:200) % X-region and Y-region
SS.xregion([50,100]);
SS.yregion([.7,1], 'FaceColor',[129,170,174]./255)
9 综合运用:聚类树
matlab">rng(3)% draw dendrogram
Data = rand(200,3);
N = 5;
Z = linkage(Data,'average');
T = cluster(Z,'maxclust',N);
cutoff = median([Z(end-(N-1),3), Z(end-(N-2),3)]);
[LineSet, ~, order] = dendrogram(Z, 0, 'Orientation', 'top');
XSet = reshape([LineSet(:).XData], 4, []);
YSet = reshape([LineSet(:).YData], 4, []);
YSet = max(max(YSet))-YSet;
close allfigure('Units','normalized', 'Position',[.1,.1,.6,.75])
SS = SSpiral(gca);
SS.set('TLim',[0,2*360+180], 'XLim',[0,200]+.5, 'YLim',[0,max(max(YSet))], 'XTick',0:5:200)
% use function obj.line to draw lines with different length
SS.line(XSet, YSet, 'Color','k', 'LineWidth',1);CList = [ 0.3569 0.0784 0.07840.6784 0.4471 0.17250.1020 0.3882 0.51760.1725 0.4196 0.43920.2824 0.2275 0.29020 0 0];
TT = T(order);
classNum = unique(TT, 'stable');
for i = 1:NtX = [find(TT==classNum(i),1,'first')-.5, find(TT==classNum(i),1,'last')+.5];lgdHdl(i) = SS.xregion(tX, 'FaceColor',CList(i,:), 'FaceAlpha',.4);
endlegend(lgdHdl, {'Set-S','Set-L','Set-A','Set-N','Set-M'})
工具函数完整代码
matlab">classdef SSpiral < handle
% Copyright (c) 2024, Zhaoxu Liu / slandarer
% =========================================================================
% @author : slandarer
% 公众号 : slandarer随笔
% 知乎 : slandarer
% -------------------------------------------------------------------------
% Zhaoxu Liu / slandarer (2024). Spiral diagram
% (https://www.mathworks.com/matlabcentral/fileexchange/164966-spiral-diagram),
% MATLAB Central File Exchange. Retrieved May 1, 2024.propertiesax,XLim, XTick, XMinorTick = 'on';YLim, YTick,Height = 1;BackgroundColor = [239,239,239]./255TLim = [0, 2*360]TickLength = [.055, .02];TickColor = [0,0,0];TickWidth = 1;XTickLabelYTickLabelTickLabelFont = {'FontSize',10, 'FontName','Times New Roman'}TickLabelFormat = @(x) num2str(x)arginList = {'XLim', 'YLim', 'TLim', 'XTick', 'YTick', 'Height',...'BackgroundColor', 'TickLength', 'TickColor', 'TickWidth',...'TickLabelFont', 'TickLabelFormat', 'TickLabel', ...'XMinorTick', 'YMinorTick', 'XTickLabel', 'YTickLabel'}ColorOrder = [ 0.2392 0.4627 0.63920.3686 0.6784 0.74510.3686 0.6314 0.46270.6549 0.3804 0.13730.4784 0.2510 0.09410.7059 0.5529 0.28240.4627 0.4902 0.4627];ColorOrderIndex = 1;BkgHdl, XTickHdl, XMinorTickHdl, YTickHdlS, YTickHdlEend
% =========================================================================methodsfunction obj = SSpiral(ax)if nargin < 1, ax = gca; endobj.ax = ax;obj.ax.NextPlot = 'add';obj.ax.XGrid = 'off';obj.ax.YGrid = 'off';obj.ax.Box = 'off';obj.ax.XColor = 'none';obj.ax.YColor = 'none';obj.ax.DataAspectRatio = [1,1,1];help SSpiralobj.drawAxes(0)end
% =========================================================================function set(obj, varargin)for i = 1:2:(length(varargin)-1)tid = ismember(obj.arginList, varargin{i});if any(tid)obj.(obj.arginList{tid}) = varargin{i+1};endendobj.drawAxes(1)end
% =========================================================================function drawAxes(obj, flag)tT = linspace(obj.TLim(1), obj.TLim(2), ceil(abs(diff(obj.TLim)))+10)./180.*pi;tX1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*cos(tT);tY1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*sin(tT);tL = vecnorm([tX1;tY1]);tX2 = tX1./tL.*(tL + obj.Height.*2.*pi);tY2 = tY1./tL.*(tL + obj.Height.*2.*pi);tX = [tX1, tX2(end:-1:1)];tY = [tY1, tY2(end:-1:1)];if flag == 0 obj.BkgHdl = fill(obj.ax, tX,tY,obj.BackgroundColor, 'EdgeColor','none');obj.BkgHdl.Annotation.LegendInformation.IconDisplayStyle='off';elseset(obj.BkgHdl, 'XData',tX, 'YData',tY, 'FaceColor',obj.BackgroundColor)endif ~isempty(obj.XLim) && ~isempty(obj.YLim)if isempty(obj.XTick)tXT = obj.getTick(obj.XLim, (abs(diff(obj.TLim))/360)*10);else tXT = obj.XTick;tXT(tXT<obj.XLim(1)) = [];tXT(tXT>obj.XLim(2)) = [];endif isempty(obj.YTick)tYT = obj.getTick(obj.YLim, 2);elsetYT = obj.XTick;tYT(tYT<obj.YLim(1)) = [];tYT(tYT>obj.YLim(2)) = [];end% ---------------------------------------------------------tMXTD = diff(tXT);tMXT = tXT(1) - tMXTD(1) : tMXTD(1)/5 : tXT(end) + tMXTD(1);tMXT(tMXT<obj.XLim(1)) = [];tMXT(tMXT>obj.XLim(2)) = [];% ---------------------------------------------------------tT = (tXT-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);tT = tT./180.*pi;tX1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*cos(tT);tY1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*sin(tT);tL = vecnorm([tX1; tY1]);tX2 = tX1./tL.*(tL + obj.Height.*2.*pi);tY2 = tY1./tL.*(tL + obj.Height.*2.*pi);tX3 = tX1./tL.*(tL + obj.Height.*2.*pi + obj.TickLength(1).*2.*pi);tY3 = tY1./tL.*(tL + obj.Height.*2.*pi + obj.TickLength(1).*2.*pi);tX = [tX2; tX3; tX2.*nan]; tX = tX(:);tY = [tY2; tY3; tY2.*nan]; tY = tY(:);% ---------------------------------------------------------tMT = (tMXT-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);tMT = tMT./180.*pi;tMX1 = (3.77 + 1.4.*abs(tMT-obj.TLim(1)./180.*pi)).*cos(tMT);tMY1 = (3.77 + 1.4.*abs(tMT-obj.TLim(1)./180.*pi)).*sin(tMT);tML = vecnorm([tMX1; tMY1]);tMX2 = tMX1./tML.*(tML + obj.Height.*2.*pi);tMY2 = tMY1./tML.*(tML + obj.Height.*2.*pi);tMX3 = tMX1./tML.*(tML + obj.Height.*2.*pi + obj.TickLength(2).*2.*pi);tMY3 = tMY1./tML.*(tML + obj.Height.*2.*pi + obj.TickLength(2).*2.*pi);tMX = [tMX2; tMX3; tMX2.*nan]; tMX = tMX(:);tMY = [tMY2; tMY3; tMY2.*nan]; tMY = tMY(:);% ---------------------------------------------------------if isempty(obj.XTickHdl)obj.XTickHdl = plot(tX, tY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth);obj.XTickHdl.Annotation.LegendInformation.IconDisplayStyle='off';elseset(obj.XTickHdl, 'XData',tX, 'YData',tY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth)endif isempty(obj.XMinorTickHdl)obj.XMinorTickHdl = plot(tMX, tMY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth, 'Visible',obj.XMinorTick);obj.XMinorTickHdl.Annotation.LegendInformation.IconDisplayStyle='off';elseset(obj.XMinorTickHdl, 'XData',tMX, 'YData',tMY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth, 'Visible',obj.XMinorTick)end% ---------------------------------------------------------tObj = findobj(obj.ax,'Tag','SSpiralTxt'); delete(tObj);for i = 1:length(tX3)tR = -90+tT(i)/pi*180;if isempty(obj.XTickLabel)tLbl = obj.TickLabelFormat(tXT(i));elsetLbl = obj.XTickLabel{min(i,length(obj.XTickLabel))};endif mod(tT(i)/pi*180, 360) >180tR = tR +180;text(obj.ax,tX3(i),tY3(i),tLbl,...'HorizontalAlignment','center', 'VerticalAlignment','top',...'Rotation', tR, obj.TickLabelFont{:},'Tag','SSpiralTxt')elsetext(obj.ax,tX3(i),tY3(i),tLbl,...'HorizontalAlignment','center', 'VerticalAlignment','bottom',...'Rotation', tR, obj.TickLabelFont{:},'Tag','SSpiralTxt')end end% ---------------------------------------------------------tX1 = cos(obj.TLim(1)/180*pi).*((tYT-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77);tY1 = sin(obj.TLim(1)/180*pi).*((tYT-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77);tT = (obj.TLim(1) - 2.*((diff(obj.TLim)>0)-.5).*(90 + 15))/180*pi;tX2 = tX1 + cos(tT).*obj.TickLength(1).*2.*pi;tY2 = tY1 + sin(tT).*obj.TickLength(1).*2.*pi;tX3 = tX1 + cos(tT).*obj.TickLength(1).*1.5.*2.*pi;tY3 = tY1 + sin(tT).*obj.TickLength(1).*1.5.*2.*pi;tX = [tX1; tX2; tX2.*nan]; tX = tX(:);tY = [tY1; tY2; tY2.*nan]; tY = tY(:);if isempty(obj.YTickHdlS)obj.YTickHdlS= plot(tX, tY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth);obj.YTickHdlS.Annotation.LegendInformation.IconDisplayStyle='off';elseset(obj.YTickHdlS, 'XData',tX, 'YData',tY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth)endtR = tT/pi*180;for i = 1:length(tX2)if isempty(obj.YTickLabel)tLbl = obj.TickLabelFormat(tYT(i));elsetLbl = obj.YTickLabel{min(i,length(obj.YTickLabel))};endif mod(tR, 360) > 90 && mod(tR, 360) < 270text(obj.ax,tX3(i),tY3(i),tLbl,...'HorizontalAlignment','right', 'VerticalAlignment','middle',...'Rotation', tR + 180, obj.TickLabelFont{:},'Tag','SSpiralTxt')elsetext(obj.ax,tX3(i),tY3(i),tLbl,...'HorizontalAlignment','left', 'VerticalAlignment','middle',...'Rotation', tR, obj.TickLabelFont{:},'Tag','SSpiralTxt')endend% ---------------------------------------------------------tX1 = cos(obj.TLim(2)/180*pi).*((tYT-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((obj.TLim(2)-obj.TLim(1))./180.*pi));tY1 = sin(obj.TLim(2)/180*pi).*((tYT-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((obj.TLim(2)-obj.TLim(1))./180.*pi));tT = (obj.TLim(2) + 2.*((diff(obj.TLim)>0)-.5).*(90))/180*pi;tX2 = tX1 + cos(tT).*obj.TickLength(1).*2.*pi;tY2 = tY1 + sin(tT).*obj.TickLength(1).*2.*pi;tX3 = tX1 + cos(tT).*obj.TickLength(1).*1.5.*2.*pi;tY3 = tY1 + sin(tT).*obj.TickLength(1).*1.5.*2.*pi;tX = [tX1; tX2; tX2.*nan]; tX = tX(:);tY = [tY1; tY2; tY2.*nan]; tY = tY(:);if isempty(obj.YTickHdlE)obj.YTickHdlE = plot(tX, tY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth);obj.YTickHdlE.Annotation.LegendInformation.IconDisplayStyle='off';elseset(obj.YTickHdlE, 'XData',tX, 'YData',tY, 'Color',obj.TickColor, 'LineWidth',obj.TickWidth)endtR = tT/pi*180;for i = 1:length(tX2)if isempty(obj.YTickLabel)tLbl = obj.TickLabelFormat(tYT(i));elsetLbl = obj.YTickLabel{min(i,length(obj.YTickLabel))};endif mod(tR, 360) > 90 && mod(tR, 360) < 270text(obj.ax,tX3(i),tY3(i),tLbl,...'HorizontalAlignment','right', 'VerticalAlignment','middle',...'Rotation', tR + 180, obj.TickLabelFont{:},'Tag','SSpiralTxt')elsetext(obj.ax,tX3(i),tY3(i),tLbl,...'HorizontalAlignment','left', 'VerticalAlignment','middle',...'Rotation', tR, obj.TickLabelFont{:},'Tag','SSpiralTxt')endendendaxis tightobj.ax.XLim = obj.ax.XLim + [-1,1].*max(obj.ax.XLim).*.1;obj.ax.YLim = obj.ax.YLim + [-1,1].*max(obj.ax.YLim).*.1;end
% =========================================================================function ticks = getTick(~, XLim, N)tXS = abs(diff(XLim)) / N;tXN = ceil(log(tXS) / log(10));tXS = round(round(tXS / 10^(tXN-2)) / 5) * 5 * 10^(tXN-2);tON = ceil(log(abs(XLim(1))) / log(10));tON(isinf(tON)) = 1;tOS = round(round(XLim(1) / 10^(tON-2)) / 5) * 5 * 10^(tON-2);ticks = tOS:tXS:XLim(2);end
% =========================================================================function barHdl = bar(obj, Y, varargin)arginListBar = {'FaceColor', 'EdgeColor', 'FaceAlpha', 'EdgeAlpha',...'LineWidth', 'BarWidth', 'CData'};barProp.FaceColor = [];barProp.EdgeColor = [0,0,0];barProp.FaceAlpha = 1;barProp.EdgeAlpha = 1;barProp.LineWidth = .5;barProp.BarWidth = 1;if isempty(varargin) || ischar(varargin{1})if size(Y,1) == 1barProp.XData = 1:size(Y,2);barProp.YData = Y;elsebarProp.XData = 1:size(Y,1);barProp.YData = Y.';endelsebarProp.XData = Y(:).';barProp.YData = varargin{1}; varargin(1) = [];if size(barProp.XData,1) == 1elsebarProp.YData = barProp.YData.';endendfor i = 1:2:(length(varargin)-1)tid = ismember(arginListBar, varargin{i});if any(tid)barProp.(arginListBar{tid}) = varargin{i+1};endend% if isempty(barProp.FaceColor)% if size(barProp.YData,1) > 1% barProp.FaceColor = obj.ColorOrder(mod(obj.ColorOrderIndex + (0:size(areaProp.YData,1)-1) -1, size(obj.ColorOrder,1)) + 1, :);% obj.ColorOrderIndex = obj.ColorOrderIndex + size(areaProp.YData,1);% else% barProp.FaceColor = obj.ColorOrder(mod(obj.ColorOrderIndex-1, size(obj.ColorOrder,1)) + 1, :);% obj.ColorOrderIndex = obj.ColorOrderIndex + 1;% end% endif isempty(barProp.FaceColor)barProp.FaceColor = obj.ColorOrder(mod(obj.ColorOrderIndex + (0:size(barProp.YData,1)-1) -1, size(obj.ColorOrder,1)) + 1, :);obj.ColorOrderIndex = obj.ColorOrderIndex + size(barProp.YData,1);endbX1 = linspace(-.5.*barProp.BarWidth, .5.*barProp.BarWidth, 50);CY1 = zeros(1,size(barProp.YData,2));CY2 = zeros(1,size(barProp.YData,2));% if size(barProp.YData,1) > 1for i = 1:size(barProp.YData,1)tX = repmat(barProp.XData(:), [1,100]) + repmat([bX1, bX1(end:-1:1)], [size(barProp.YData,2),1]);tY = [repmat(barProp.YData(i,:).', [1,50]), zeros(size(barProp.YData,2),50)] + repmat(CY1(:).*(barProp.YData(i,:).'>0) + CY2(:).*(barProp.YData(i,:).'<0), [1,100]);CY1 = CY1 + barProp.YData(i,:).*(barProp.YData(i,:)>0);CY2 = CY2 + barProp.YData(i,:).*(barProp.YData(i,:)<0);tT = (tX-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);tR = (tY-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((tT-obj.TLim(1))./180.*pi);tT = tT.'; tR = tR.';barHdl(i,:) = fill(obj.ax, cos(tT./180.*pi).*tR,sin(tT./180.*pi).*tR, barProp.FaceColor(i,:), 'EdgeColor',barProp.EdgeColor,...'LineWidth',barProp.LineWidth, 'FaceAlpha',barProp.FaceAlpha, 'EdgeAlpha',barProp.EdgeAlpha);for j = 2:length(barHdl)barHdl(i,j).Annotation.LegendInformation.IconDisplayStyle='off';endend% else% % for i = 1:size(barProp.YData,2)% % tX = barProp.XData(i) + [-.5.*barProp.BarWidth, bX, .5.*barProp.BarWidth];% % tY = [barProp.YData(i), zeros(1,50), barProp.YData(i)];% % tT = (tX-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);% % tR = (tY-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((tT-obj.TLim(1))./180.*pi);% % barHdl(i) = fill(obj.ax, cos(tT/180*pi).*tR,sin(tT/180*pi).*tR, barProp.FaceColor, 'EdgeColor',barProp.EdgeColor,...% % 'LineWidth',barProp.LineWidth, 'FaceAlpha',barProp.FaceAlpha, 'EdgeAlpha',barProp.EdgeAlpha);% % end% tX = repmat(barProp.XData(:), [1,100]) + repmat([bX1, bX1(end:-1:1)], [size(barProp.YData,2),1]);% tY = [repmat(barProp.YData(:), [1,50]), zeros(size(barProp.YData,2),50)];% tT = (tX-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);% tR = (tY-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((tT-obj.TLim(1))./180.*pi);% tT = tT.'; tR = tR.';% barHdl = fill(obj.ax, cos(tT./180.*pi).*tR,sin(tT./180.*pi).*tR, barProp.FaceColor, 'EdgeColor',barProp.EdgeColor,...% 'LineWidth',barProp.LineWidth, 'FaceAlpha',barProp.FaceAlpha, 'EdgeAlpha',barProp.EdgeAlpha);% for i = 2:length(barHdl)% barHdl(i).Annotation.LegendInformation.IconDisplayStyle='off';% end% endendfunction areaHdl = area(obj, X, Y, varargin)arginListBar = {'FaceColor', 'EdgeColor', 'FaceAlpha', 'EdgeAlpha',...'LineWidth', 'BarWidth', 'CData'};areaProp.FaceColor = [];areaProp.EdgeColor = 'none';areaProp.FaceAlpha = .5;areaProp.EdgeAlpha = 1;areaProp.LineWidth = .5;areaProp.XData = X(:).';areaProp.YData = Y.';for i = 1:2:(length(varargin)-1)tid = ismember(arginListBar, varargin{i});if any(tid)areaProp.(arginListBar{tid}) = varargin{i+1};endendif isempty(areaProp.FaceColor)areaProp.FaceColor = obj.ColorOrder(mod(obj.ColorOrderIndex + (0:size(areaProp.YData,1)-1) -1, size(obj.ColorOrder,1)) + 1, :);obj.ColorOrderIndex = obj.ColorOrderIndex + size(areaProp.YData,1);endbX1 = linspace(areaProp.XData(1), areaProp.XData(end), length(areaProp.XData)*10);CY1 = zeros(1, length(areaProp.XData)*10);CY2 = zeros(1, length(areaProp.XData)*10);for i = 1:size(areaProp.YData,1)tX = [bX1, bX1(end:-1:1)];tYq = interp1(areaProp.XData, areaProp.YData(i,:), bX1);tY = [tYq, zeros(1,length(bX1))] + [CY1,CY1(end:-1:1)].*([tYq,tYq(end:-1:1)]>0) + [CY2,CY2(end:-1:1)].*([tYq,tYq(end:-1:1)]<0);%repmat(CY1.*(tYq>0) + CY2.*(tYq<0), [1,2]);CY1 = CY1 + tYq.*(tYq>0);CY2 = CY2 + tYq.*(tYq<0);tT = (tX-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);tR = (tY-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((tT-obj.TLim(1))./180.*pi);areaHdl(i) = fill(obj.ax, cos(tT./180.*pi).*tR,sin(tT./180.*pi).*tR, areaProp.FaceColor(i,:), 'EdgeColor',areaProp.EdgeColor,...'LineWidth',areaProp.LineWidth, 'FaceAlpha',areaProp.FaceAlpha, 'EdgeAlpha',areaProp.EdgeAlpha);endendfunction plotHdl = plot(obj, X, Y, varargin)if any(size(X) == 1)tN = length(X);elsetN = size(X,1);endtTq = linspace(1, tN, (tN-1)*10+1);tX = interp1(1:tN, X, tTq);tY = interp1(1:tN, Y, tTq);tT = (tX-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);tR = (tY-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((tT-obj.TLim(1))./180.*pi);plotHdl = plot(obj.ax, cos(tT./180.*pi).*tR,sin(tT./180.*pi).*tR, 'MarkerIndices',1:10:(tN-1)*10+1, varargin{:});endfunction lineHdl = line(obj, X, Y, varargin)if any(size(X) == 1)tN = length(X);elsetN = size(X,1);endfor i = 1:size(Y,2)tNq = ceil((max(max(X(:,i)))-min(min(X(:,i))))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)))/2+10;tTq = linspace(1, tN, tNq);tX = interp1(1:tN, X(:,i), tTq);tY = interp1(1:tN, Y(:,i), tTq);tT = (tX-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);tR = (tY-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((tT-obj.TLim(1))./180.*pi);lineHdl(i) = plot(obj.ax, cos(tT./180.*pi).*tR,sin(tT./180.*pi).*tR, varargin{:},'Marker','none');endendfunction scatterHdl = scatter(obj, X, Y, varargin)tT = (X-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)).*2.*((diff(obj.TLim)>0)-.5) + obj.TLim(1);tR = (Y-obj.YLim(1))./abs(diff(obj.YLim)).*(obj.Height.*2.*pi) + 3.77 + 1.4.*abs((tT-obj.TLim(1))./180.*pi);scatterHdl = scatter(obj.ax, cos(tT./180.*pi).*tR,sin(tT./180.*pi).*tR, varargin{:});endfunction regionHdl = xregion(obj, Lim, varargin)Lim = (Lim-obj.XLim(1))./abs(diff(obj.XLim)).*abs(diff(obj.TLim)) + obj.TLim(1);tT = linspace(Lim(1), Lim(2), ceil(abs(diff(Lim)))+10)./180.*pi;tX1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*cos(tT);tY1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*sin(tT);tL = vecnorm([tX1;tY1]);tX2 = tX1./tL.*(tL + obj.Height.*2.*pi);tY2 = tY1./tL.*(tL + obj.Height.*2.*pi);tX = [tX1, tX2(end:-1:1)];tY = [tY1, tY2(end:-1:1)];regionHdl = fill(obj.ax, tX,tY, [114,146,184]./255, 'EdgeColor','none', 'FaceAlpha',.5, varargin{:});endfunction regionHdl = yregion(obj, Lim, varargin)tT = linspace(obj.TLim(1), obj.TLim(2), ceil(abs(diff(obj.TLim)))+10)./180.*pi;tX1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*cos(tT);tY1 = (3.77 + 1.4.*abs(tT-obj.TLim(1)./180.*pi)).*sin(tT);tL = vecnorm([tX1;tY1]);tX2 = tX1./tL.*(tL + obj.Height.*2.*pi.*(Lim(1)-obj.YLim(1))./abs(diff(obj.YLim)));tY2 = tY1./tL.*(tL + obj.Height.*2.*pi.*(Lim(1)-obj.YLim(1))./abs(diff(obj.YLim)));tX3 = tX1./tL.*(tL + obj.Height.*2.*pi.*(Lim(2)-obj.YLim(1))./abs(diff(obj.YLim)));tY3 = tY1./tL.*(tL + obj.Height.*2.*pi.*(Lim(2)-obj.YLim(1))./abs(diff(obj.YLim)));tX = [tX2, tX3(end:-1:1)];tY = [tY2, tY3(end:-1:1)];regionHdl = fill(obj.ax, tX,tY, [114,146,184]./255, 'EdgeColor','none', 'FaceAlpha',.5, varargin{:});endend
end
完
以上已经是完整代码,未经允许本代码请勿作商业用途,引用的话可以引用我file exchange上的链接,可使用如下格式:
- Zhaoxu Liu / slandarer (2024). Spiral diagram (https://www.mathworks.com/matlabcentral/fileexchange/164966-spiral-diagram), MATLAB Central File Exchange. Retrieved May 1, 2024.
若转载请保留以上file exchange链接及本文链接!!!!!