You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
How to add legend (or colorbar) to volshow/labelvolshow output?
16 views (last 30 days)
Show older comments
Hi, can someone help me to add a legend to a panel created by labelvolshow? I managed to add a title but I really don't know how to put a legend (or at least a colorbar, even if I know it wouldn't be the same thing). Any kind of "legend" is accept: I mean, not just the output of the classic legend function; also some strings, written in the color of the data, can be fine for example..any way to categorize the output is welcome, the important thing is that I'd like it to be automatically generated by the code - no interactions with the panel required.
This is how I add a title:
view_panel = uipanel(figure,'Title',"Titolo");
view_panel.FontSize=14;
view_panel.TitlePosition='centertop';
labelvolshow(volume_labeled,'Parent',view_panel);
Thanks in advance
Accepted Answer
Voss
on 25 May 2022
Maybe something like this can be a start:
volume_labeled = randi(10,[5 5 5]);
view_panel = uipanel(figure,'Title',"Titolo");
view_panel.FontSize=14;
view_panel.TitlePosition='centertop';
h = labelvolshow(volume_labeled,'Parent',view_panel);
NC = size(h.LabelColor,1);
ax = axes( ...
'Parent',view_panel, ...
'Units','normalized', ...
'Position',[0.93 0 0.07 1], ...
'Visible','off', ...
'YLim',[0 10], ...
'CLim',[0 10], ...
'Colormap',h.LabelColor);
p = patch( ...
'Parent',ax, ...
'XData',repmat([0; 1; 1; 0],1,NC), ...
'YData',[0;0;1;1]+(0:NC-1), ...
'FaceColor','flat', ...
'FaceVertexCData',ax.Colormap);
t = text(ax,0.5*ones(1,NC),(1:NC)-0.5,sprintfc('%d',1:NC), ...
'HorizontalAlignment','center');
t(1).Color = [1 1 1];
17 Comments
Simone Cotta Ramusino
on 25 May 2022
Thanks a lot! It is a bit poor and verbose but it's the best result obtained so far, and probably the best possible.
Do you know a way to use sprintfc (or directly text) to print a multiline of text? I'd like something like this:
"Cluster 1 -
Mean=1 Kg"
for each block of the colorbar/legend. Even in a single line is ok, but I am afraid it would come out of the edges.
I try sprintf but it replicates all the lines:
"Cluster1 - mean=10Kg Cluster2 - mean=17Kg Cluster 3 - mean=9Kg"
for each block.
Thanks again
Voss
on 25 May 2022
. -_
volume_labeled = randi(10,[5 5 5]);
view_panel = uipanel(figure,'Title',"Titolo");
view_panel.FontSize=14;
view_panel.TitlePosition='centertop';
h = labelvolshow(volume_labeled,'Parent',view_panel);
NC = size(h.LabelColor,1);
ax = axes( ...
'Parent',view_panel, ...
'Units','normalized', ...
'Position',[0.85 0 0.15 1], ...
'Visible','off', ...
'YDir','reverse', ...
'YLim',[0 10], ...
'CLim',[0 10], ...
'Colormap',h.LabelColor);
p = patch( ...
'Parent',ax, ...
'XData',repmat([0; 1; 1; 0],1,NC), ...
'YData',[0;0;1;1]+(0:NC-1), ...
'FaceColor','flat', ...
'FaceVertexCData',ax.Colormap);
means = [10 17 9 randi(20,1,NC-3)];
labels = arrayfun(@(x,y)sprintf('Cluster %d -\nMean=%gkg',x,y), ...
1:NC,means,'UniformOutput',false);
t = text(ax,ones(1,NC),(1:NC)-0.5,labels, ...
'HorizontalAlignment','right');
t(1).Color = [1 1 1];
Simone Cotta Ramusino
on 26 May 2022
Thank you, you are really a master at this! I really appreciate your help
Simone Cotta Ramusino
on 26 May 2022
Just one more thing, if I may ask: now that we have created an axes structure, I found that the panel accepts and shows the classic legend box. But if I write something like:
legend('Cluster1','Cluster2','Cluster3')
it shows correctly just the first one, with the right color, and this warning appears:
Warning: Ignoring extra legend entries.
> In legend>process_inputs (line 592)
In legend>make_legend (line 319)
In legend (line 263)
Is there a way to show the classic legend box, with the lines I indicated earlier? I think it would be neater.
Thanks again for your efforts.
Walter Roberson
on 26 May 2022
You only have one graphics object, a single patch().
You will need to create extra objects with position nan or inf and whatever attributes you need. If you want sample swaths of color then you will need to create image() or surface() or patch() objects in order to get legend to show the swath.
Simone Cotta Ramusino
on 27 Sep 2022
Sorry, I got another doubt about this. Let's consider the cube example created by @Voss. Imagine I have 5,10 or 20 clusters: I want to represent it without visualizing the last cluster (that in my case I made sure it represents the background). So, I set the LabelOpacity option as a vector of 1, except the last one 0. This works up to 5 clusters, but when I switch to 6 or more, the last cluster show up, with an opacity of about 0.5 I think (it is not entirely opaque).
Any hint to avoid this? I will attached the figures as soon as possible
Thanks
Simone Cotta Ramusino
on 27 Sep 2022
Yes, you're right, it's an option of labelvolshow. I wrote this:
h=labelvolshow(clustered_E,'Parent',view_panel,'BackgroundColor','c','LabelOpacity',LabelOpacity,'LabelVisibility',LabelVisibility,'ShowIntensityVolume',0,'VolumeOpacity',0);
where clustered_E is the labeled volume, LabelOpacity the opacity of the labels (in the form [1;1;1;...;0]), LabelVisibility the visibility of labels (always [1;1;1;...;0]) and ShowIntensityVolume the option, if I got it right, to show the original volume under the labeled one. Firstly (for the first 5 clusters) LabelOpacity alone was enough to work, I added the other options later as an attempt for 6 or more clusters but it didn't work.
Simone Cotta Ramusino
on 28 Sep 2022
This is the code I used:
tuttiE=E(:); % list of values to be classified
n_cluster=6; % works as I wish up to 5 clusters
[clusterindex_E,centroids_E]=kmeans(tuttiE,(n_cluster+1),'MaxIter',500,'Replicates',5); % I add a cluster because I have to consider the bg, which I set to a much larger value on purpose
clustered_E=sort_ind_cluster(clusterindex_E,E,(n_cluster+1)); % my function that sorts the cluster indices proportionally to the values they contain
centroids_E=sort(centroids_E);
% Visualization
LabelOpacity=ones(n_cluster,1);
LabelOpacity=cat(1,LabelOpacity,0); % last element=0 to erase the background
LabelVisibility=ones(n_cluster,1);
LabelVisibility=logical(cat(1,LabelVisibility,0));
view_panel=uipanel(figure,'Title',"Property - "+num2str(n_cluster)+" cluster");
view_panel.FontSize=14; view_panel.TitlePosition='centertop';
h=labelvolshow(clustered_E,'Parent',view_panel,'BackgroundColor','c','LabelOpacity',LabelOpacity,'LabelVisibility',LabelVisibility,'ShowIntensityVolume',0,'VolumeOpacity',0,'VolumeThreshold',0);
ax=axes('Parent',view_panel,'Units','normalized','Position',[0.80 0 0.20 1], ...
'Visible','off','YLim',[0 n_cluster],'CLim',[0 n_cluster],'Colormap',h.LabelColor);
p=patch('Parent',ax,'XData',repmat([0; 1; 1; 0],1,n_cluster), ...
'YData',[0;0;1;1]+(0:n_cluster),'FaceColor','flat','FaceVertexCData',ax.Colormap);
tags=arrayfun(@(x,y)sprintf('Cluster %d -\n Centroide=%.2e',x,y),1:n_cluster, ...
centroids_E(1:n_cluster)','UniformOutput',false);
t=text(ax,0.5*ones(1,n_cluster),(1:n_cluster)-0.5,tags,'HorizontalAlignment','center', ...
'Color','white','FontSize',11,'FontWeight','normal');
As I told, it should work even without LabelVisibility, ShowIntensityVolume, VolumeOpacity, VolumeThreshold (at least it works up to 5 cluster), but I left them anyway. I am attaching the results for 6 and 5 cluster respectively
Walter Roberson
on 30 Sep 2022
Looks like I would need more reproduction steps
arrayfun(@do_label, [5, 10])
function do_label(N)
fig = figure();
volume_labeled = randi(N,[5 5 5]);
view_panel = uipanel(fig,'Title',"Titolo");
view_panel.FontSize=14;
view_panel.TitlePosition='centertop';
LabelOpacity = [1; zeros(N-1,1)];
LabelVisibility = logical(LabelOpacity);
h = labelvolshow(volume_labeled,'Parent',view_panel, 'LabelOpacity',LabelOpacity,'LabelVisibility',LabelVisibility);
NC = size(h.LabelColor,1);
ax = axes( ...
'Parent',view_panel, ...
'Units','normalized', ...
'Position',[0.85 0 0.15 1], ...
'Visible','off', ...
'YDir','reverse', ...
'YLim',[0 10], ...
'CLim',[0 10], ...
'Colormap',h.LabelColor);
p = patch( ...
'Parent',ax, ...
'XData',repmat([0; 1; 1; 0],1,NC), ...
'YData',[0;0;1;1]+(0:NC-1), ...
'FaceColor','flat', ...
'FaceVertexCData',ax.Colormap);
means = [10 17 9 randi(20,1,NC-3)];
labels = arrayfun(@(x,y)sprintf('Cluster %d -\nMean=%gkg',x,y), ...
1:NC,means,'UniformOutput',false);
t = text(ax,ones(1,NC),(1:NC)-0.5,labels, ...
'HorizontalAlignment','right');
t(1).Color = [1 1 1];
end
Walter Roberson
on 30 Sep 2022
A problem with the k-means algorithm is that it always has to assign every point to some cluster. So for example if you had green leaves with brown spots and blue sky around the leaves, and you asked for 2 clusters, then it would not give you one cluster for the green and one cluster for the brown spots, because it would have to assign the blue to one of the two clusters.
In your 6 cluster version, it looks to me as if your background got included as one of the clusters.
Simone Cotta Ramusino
on 30 Sep 2022
I see what you mean, but it can't be like that: first of all, it would not have a different (almost 50% I'd say) opacity value, because the other six clusters are 100% opaque; and you can see that the red of the bg is different from the other two red shades in the part. Also, I tried to change the color of the 7th label, and only the bg color (the shaded red block) has changed.
Lastly, I checked the values of this 7th cluster, and it only contains the value (the unique value, far greater than the others) of the background as I have specified it. So the problem must be elsewhere.
Maybe I'll open a new topic to talk about it better
Simone Cotta Ramusino
on 30 Sep 2022
Sorry @Walter Roberson, apparently I was partly wrong and you were right: if I hide the penultimate cluster the shaded block disappear. But the odd thing is, if show only that last-but-one cluster, it appears the right one AND this strange shade (here, with 7 clusters, in green). I just can't figure it out!
Walter Roberson
on 30 Sep 2022
unfortunately I do not seem to replicate this with a minimal test. Would it be possible for you to attach data and enough code to reproduce the problem?
Simone Cotta Ramusino
on 1 Oct 2022
Attaching the whole process would be too cumbersome. Anyway, if you want to try, you can create sample E data like this:
E=ones(5,5,3);
E(1,:,:)=100000; % defining bg (far higher)
E(5,:,:)=100000;
E(:,1,:)=100000;
E(:,5,:)=100000;
E(2:4,2:4,1)=randi(100,3); % defining much lower values
E(2:4,2:4,2)=randi(100,3);
E(2:4,2:4,3)=randi(100,3);
and then use the visualization code I've attached before
tuttiE=E(:);
n_cluster=6; % and so on...
I've tried with this and I get the same problem so you can try too, if u want. Thanks again
More Answers (0)
See Also
Categories
Find more on Data Distribution 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!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)