How to make sparsity pattern graph with grouping
7 views (last 30 days)
Show older comments
Hi. I would like to create a graph looking like the following:
The rows correspond to periods (months), and the columns to a set of features/predictors/X's. The features have been assigned to a category, which corresponds to the different colors.
The data that I would like to plot something similar for, are in the following form (-assuming we have 30 periods, and 15 perdictors):
%Create a Sparse Matrix M:
T=30; N=15;
M=zeros(T,N);
for i=1:T
M(i,randsample(1:N, 6, false))=1;
end
TT = array2timetable(M,'RowTimes',dateshift(datetime('today'),'end','month',-T+1:0),'VariableNames',"x"+string(1:N))
c = [repmat("Financial",[1,5]) repmat("Econ",[1,8]) repmat("Survey",[1,2])]';
c = c(randsample(1:N,N,false));
categoriez = array2table(c,'RowNames',"x"+string(1:N),"VariableNames","categ")
I would like to create a graph like the one on the top, using the data in timetable TT and table categoriez. Any help would be appreciated!
0 Comments
Accepted Answer
Adam Danz
on 17 Apr 2024
Edited: Adam Danz
on 17 Apr 2024
Using pcolor
This solution uses pcolor and converts the table of 0s and 1s into grouping values that are used to assign color to each cell.
OP's demo code
T=30; N=15;
M=zeros(T,N);
for i=1:T
M(i,randsample(1:N, 6, false))=1;
end
TT = array2timetable(M,'RowTimes',dateshift(datetime('today'),'end','month',-T+1:0),'VariableNames',"x"+string(1:N));
c = [repmat("Financial",[1,5]) repmat("Econ",[1,8]) repmat("Survey",[1,2])]';
c = c(randsample(1:N,N,false));
categoriez = array2table(c,'RowNames',"x"+string(1:N),"VariableNames","categ");
% Convert strings to categorical
categoriez.categ = categorical(categoriez.categ);
% Convert the categoricals to integers for grouping
catVals = double(categoriez.categ);
% Replace the 0s in TT with NaNs and the 1s with the grouping values.
m = TT{:,:};
m(m==0) = nan;
m = m.* catVals.';
m(:,end+1) = nan; % pad 1 column so last column of data is shown
m(end+1,:) = nan; % pad 1 row so last row of data is shown
% Plot the results.
h = pcolor(1:width(m),[TT.Properties.RowTimes;NaT],m);
% Set color
ncats = numel(unique(catVals));
colormap(jet(ncats)) % nx3 matrix where n = number of categories
% Show colorbar with centered ticks
cb = colorbar();
cb.Ticks = linspace(1,ncats,ncats+1) + (ncats-1)/(ncats*2);
cb.TickLabels = categories(categoriez.categ);
Using scatter
Another approach is to use scatter which, unlike line objects, lets you control the color of each marking by setting the cdata.
% Find the row and column coordinates of 1 values.
[row,col] = find(TT{:,:});
% Compute the color values (m)
% Convert strings to categorical
categoriez.categ = categorical(categoriez.categ);
% Convert the categoricals to integers for grouping
catVals = double(categoriez.categ);
% Replace the 0s in TT with NaNs and the 1s with the grouping values.
m = TT{:,:};
m(m==0) = nan;
m = m.* catVals.';
% plot the scatter with filled markers
scatter(col,TT.Properties.RowTimes(row),60,m(~isnan(m)),'filled')
% Set color
ncats = numel(unique(catVals));
colormap(jet(ncats)) % nx3 matrix where n = number of categories
% Show colorbar with centered ticks
cb = colorbar();
cb.Ticks = linspace(1,ncats,ncats+1) + (ncats-1)/(ncats*2);
cb.TickLabels = categories(categoriez.categ);
4 Comments
Adam Danz
on 24 Apr 2024
Edited: Adam Danz
on 24 Apr 2024
You could use a legend instead but you'll need to use a hack to create the legend objects.
Add this to your code following the scatter example. I did not test this, check that the order of colors and labels are correct.
colors = jet(ncats);
names = categories(categoriez.categ);
hold on
h = gobjects(1,ncats);
for i = 1:height(colors)
h(i) = plot(nan,nan,'o',...
'MarkerEdgeColor','none',...
'MarkerFaceColor',colors(i,:),...
'MarkerSize',8, ...
'DisplayName', names{i});
end
legend(h)
More Answers (0)
See Also
Categories
Find more on Discrete Data Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!