How to make sparsity pattern graph with grouping
3 次查看(过去 30 天)
显示 更早的评论
Hi. I would like to create a graph looking like the following:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1671636/image.png)
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 个评论
采纳的回答
Adam Danz
2024-4-17
编辑:Adam Danz
2024-4-17
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 个评论
Adam Danz
2024-4-24
编辑:Adam Danz
2024-4-24
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)
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!