0


MATLAB | 如何绘制github同款日历热力图

应粉丝要求,出一个类似于github热图的日历热力图,大概长这样:

依旧工具函数放在文末,如有bug请反馈并去gitee下载更新版。


使用教程

使用方式有以下几种会慢慢讲到:

  • heatmapDT(Year,T,V)
  • heatmapDT(Year,T,V,MonLim)
  • heatmapDT(ax,Year,T,V)
  • heatmapDT(ax,Year,T,V,MonLim)

基础使用

随便构造一组数据:

% 构造一组比较连续但是有波动的数据
T=datetime(2022,1,1):datetime(2022,12,31);
t=linspace(1,length(T),10);
tV=rand(size(t));
V=interp1(t,tV,1:length(T))+rand(1,[length(T)])./3;

这组数据大概是这样的:

绘制日历热力图并调整大小:

% 绘制日历热图heatmapDT(2022,T,V)% 调整图窗和坐标区域大小set(gcf,'Position',[100,500,1500,260])set(gca,'Position',[.03,.03,1-.1,1-.1])

修改colormap(当然clim和caxis也能用)。

colormap(pink)

随便再换点颜色:

自己定义点颜色:

CM=[1.00001.00000.85100.94870.98000.73690.86170.94580.69950.72910.89380.71090.52370.81390.73080.34330.74650.75580.20360.66100.76290.11550.55040.74440.12980.40500.67590.13980.27880.61600.11410.17930.51620.03140.11370.3451];
CMX=linspace(0,1,size(CM,1));
CMXX=linspace(0,1,256)';
CM=[interp1(CMX,CM(:,1),CMXX,'pchip'),...interp1(CMX,CM(:,2),CMXX,'pchip'),...interp1(CMX,CM(:,3),CMXX,'pchip')];colormap(CM)

当然可以配合slanCM配色工具:https://slandarer.blog.csdn.net/article/details/127719784

使用效果:

空缺值

比如数据是2022年的,但是只有前半年数据(有空缺,那么空缺部分会用灰色补齐):

% 构造一组比较连续但是有波动的数据
T=datetime(2022,1,1):datetime(2022,6,30);
t=linspace(1,length(T),10);
tV=rand(size(t));
V=interp1(t,tV,1:length(T))+rand(1,[length(T)])./3;% 绘制日历热图heatmapDT(2022,T,V)% 调整图窗和坐标区域大小set(gcf,'Position',[100,500,1500,260])set(gca,'Position',[.03,.03,1-.1,1-.1])

只画部分月份

猜到会有人想要这样的功能,只需要添加MonLim参数[a,b]即可,其中

    1
   
   
    ≤
   
   
    a
   
   
    ≤
   
   
    b
   
   
    ≤
   
   
    12
   
  
  
   1\leq a\leq b\leq 12
  
 
1≤a≤b≤12,比如绘制二月热力图:
% 构造一组比较连续但是有波动的数据
T=datetime(2022,1,1):datetime(2022,12,31);
t=linspace(1,length(T),10);
tV=rand(size(t));
V=interp1(t,tV,1:length(T))+rand(1,[length(T)])./3;% 绘制日历热图heatmapDT(2022,T,V,[2,2])% 调整图窗和坐标区域大小set(gcf,'Position',[100,100,800,600])set(gca,'Position',[.15,.15,1-.3,1-.3])

2-3月:

heatmapDT(2022,T,V,[2,3])

1-3月:

heatmapDT(2022,T,V,[1,3])

多子图

就将第一个参数设置为坐标区域即可,以下不用随机生成的数据了,用一个matlab Financial Toolbox工具箱自带的数据:

load SimulatedStock.mat 

T=TMW.Time;
V=TMW.High;% 绘制三个热力图
ax1=axes(gcf,'Position',[.06,2/3+.01,1-.07,1/3-.03]);heatmapDT(ax1,2013,T,V)
ax2=axes(gcf,'Position',[.06,1/3+.01,1-.07,1/3-.03]);heatmapDT(ax2,2014,T,V)
ax3=axes(gcf,'Position',[.06,0+.01,1-.07,1/3-.03]);heatmapDT(ax3,2015,T,V)% 绘制标题并调整位置
TT=title(ax1,{'Simulated Stock heatmap'},'FontSize',18,'FontWeight','bold','FontName','Times New Roman');
TT.Position(2)=-.1;set(gcf,'Position',[100,100,1200,620])

随便试试自带colormap配色:

随便试试slanCM工具配色:


工具函数完整代码

functionheatmapDT(varargin)% @author:slandarer% Zhaoxu Liu / slandarer (2023). % calendar heatmap (https://www.mathworks.com/matlabcentral/fileexchange/125835-calendar-heatmap), % MATLAB Central File Exchange. 检索来源 2023/3/7.% 参数获取ifisa(varargin{1},'matlab.graphics.axis.Axes')
    ax=varargin{1};varargin(1)=[];else
    ax=gca;end
YY=varargin{1};
DT=varargin{2};
VAL=varargin{3};
MLim=[1,12];try
    MLim=varargin{4};catchend% 截取该年份日期及数值
BeginTime=datetime(YY,1,1);
EndTime=datetime(YY+1,1,1);
VAL=VAL(DT>=BeginTime&DT<EndTime);
DT=DT(DT>=BeginTime&DT<EndTime);% 范围计算
DayName={'Mon','Tue','Wed','Thu','Fri','Sat','Sun'};if MLim>=12
    FDT=datetime(YY,MLim(1),1):(datetime(YY+1,1,1)-1);else
    FDT=datetime(YY,MLim(1),1):(datetime(YY,MLim(2)+1,1)-1);end[DayNumber,~]=weekday(FDT);DayNumber(DayNumber==1)=8;
DayNumber=DayNumber-1;
TB=tabulate(DayNumber);
XLen=max(TB(:,2));% 坐标区域修饰
hold on
ax.DataAspectRatio=[1,1,1];
ax.YLim=[.5,7.5];
ax.YDir='reverse';
ax.YTick=1:7;
ax.YTickLabel=DayName;
ax.YAxisLocation='right';
ax.FontName='Monospaced';
ax.FontWeight='bold';
ax.XColor=[.3,.3,.3];
ax.YColor=[.3,.3,.3];% ax.Title.String=num2str(YY);
ax.FontSize=12;% ax.LooseInset=[0,0,0,0];
FHdl=fill(ax,ax.XLim([1,1,2,2]),ax.YLim([1,2,2,1]),[1,1,1],'EdgeColor','w','LineWidth',2);% 绘制灰色方块
xs=[-.5,-.5,.5,.5];ys=[-.5,.5,.5,-.5];
XList=zeros(1,length(FDT)); 
YList=zeros(1,length(FDT));fori=1:length(FDT)XList(i)=sum(DayNumber==1&(1:length(FDT)<=i))+1;YList(i)=DayNumber(i);fill(ax,xs+XList(i),ys+YList(i),[.8,.8,.8],'EdgeColor','w','LineWidth',1)end% 绘制热力方块fori=1:length(FDT)
    tPos=find(FDT(i)==DT,1);if~isempty(tPos)fill(ax,xs+XList(i),ys+YList(i),VAL(tPos),'EdgeColor','w','LineWidth',1)endend% 绘制外轮廓
MonNumber=month(FDT);
XDList=zeros(1,MLim(2)-MLim(1)+1);
n=1;fori=MLim(1):MLim(2)
    XU=XList(MonNumber==i&DayNumber==1);plot([min(XU)-.5,max(XU)+.5],[.5,.5],'Color',[0,0,0],'LineWidth',1);
    XD=XList(MonNumber==i&DayNumber==7);XDList(n)=mean(XD);n=n+1;plot([min(XD)-.5,max(XD)+.5],[7.5,7.5],'Color',[0,0,0],'LineWidth',1);
    YL=YList(MonNumber==i&XList==max(XU));plot([max(XU)+.5,max(XU)+.5],[min(YL)-.5,max(YL)+.5],'Color',[0,0,0],'LineWidth',1);plot([max(XU)-.5,max(XU)-.5],[min(max(YL)+1,8)-.5,7+.5],'Color',[0,0,0],'LineWidth',1);plot([max(XU)+.5,max(XU)-.5],[max(YL)+.5,max(YL)+.5],'Color',[0,0,0],'LineWidth',1);ifi==MLim(1)
        YR=YList(MonNumber==i&XList==min(XD));plot([min(XD)-.5,min(XD)-.5],[min(YR)-.5,max(YR)+.5],'Color',[0,0,0],'LineWidth',1);plot([min(XD)+.5,min(XD)+.5],[max(min(YR)-1,0)+.5,.5],'Color',[0,0,0],'LineWidth',1);plot([min(XD)-.5,min(XD)+.5],[min(YR)-.5,min(YR)-.5],'Color',[0,0,0],'LineWidth',1);endend
ax.XLim=[.5,max(XList)+.5];
FHdl.XData=ax.XLim([1,1,2,2]);
ax.XTick=XDList;
MonName={'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'};
ax.XTickLabel=MonName(MLim(1):MLim(2));% 设置colormap
CM=[1.00001.00000.89800.98330.99370.80600.96080.98510.71970.89800.96000.67370.82800.93120.62820.73590.89150.58430.63690.84860.54040.52600.80050.49650.41310.74820.44520.29800.69180.38670.21570.61960.33070.15290.53800.27630.08240.47370.24390.00920.41520.218800.34380.190100.27060.1608];disp(char([6497117116104111114325832,...1151089711010097114101114]))
CMX=linspace(0,1,size(CM,1));
CMXX=linspace(0,1,256)';
CM=[interp1(CMX,CM(:,1),CMXX,'pchip'),...interp1(CMX,CM(:,2),CMXX,'pchip'),...interp1(CMX,CM(:,3),CMXX,'pchip')];colormap(ax,CM);
CB=colorbar(ax);
CB.LineWidth=1;% 绘制年份标题text(ax,-0.2,4,num2str(YY),'Rotation',90,'HorizontalAlignment','center','VerticalAlignment','baseline',...'FontSize',27,'FontWeight','bold','Color',[.6,.6,.6])end

本文转载自: https://blog.csdn.net/slandarer/article/details/129393798
版权归原作者 slandarer 所有, 如有侵权,请联系我们删除。

“MATLAB | 如何绘制github同款日历热力图”的评论:

还没有评论