Add legend to imagesc
46 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
I have a matrix A, whose values are intergers 0:6.
figure,imagesc(A)
I want to add a legend for value 1 to 6, without change the color of the map. How can I do it? Thanks
0 Kommentare
Antworten (1)
Walter Roberson
am 23 Feb. 2017
You will need to use something like,
A = randi([0 6], 20, 30);
cmap = prism(7);
image(A);
colormap(cmap);
hold on;
for K = 1 : 7; hidden_h(K) = surf(uint8(K-[1 1;1 1]), 'edgecolor', 'none'); end
hold off
uistack(hidden_h, 'bottom');
legend(hidden_h, {'zeroth', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth'} )
Note my change from imagesc to image. You should not use imagesc if you want to be able to identify each value with a different color, because imagesc maps data according to the values actually used in the image. If you happened to have an image that had no 0 or 1 (for example) then you would not want the colors for the other entries to change.
2 Kommentare
Walter Roberson
am 23 Feb. 2017
A = randi([0 6], 20, 30);
imagesc(A);
colormap(cmap);
minA = min(A(:));
maxA = max(A(:));
legends = {'first', 'second', 'third', 'fourth', 'fifth', 'sixth'};
hold on;
for K = minA : maxA; hidden_h(K-minA+1) = surf(uint8([K K;K K]), 'edgecolor', 'none'); end
hold off
uistack(hidden_h, 'bottom');
legend(hidden_h, legends(minA:maxA) )
You might notice with this that not all of the legends always appear. That is deliberate.
Suppose you have an A that only holds values 2, 3, 4, 5, with no entries for 0, 1, or 6. Then imagesc(A) is going to map 2 into the first color in your color map, and is going to map 5 into the last entry in your color map -- the colors for any particular value are going to depend not on the value itself but rather on how wide the range of values is in A.
Now, for that A that does not have any entries for 0, 1, or 6, you ask to put up legends for 1 through 6. But there is no content with 1 and no content with 6. What color is associated with that non-existent content? Answer: they are outside the color map, because your use of imagesc() defines the color map to be spread out over the used values.
You might be tempted to generate them anyhow and ignore them, but in order to get the color right for the swaths of color for the legend, you have to generate a graphics object with that value. And if you generate a graphics swath with value 1 or 6, then you change the used range of values for the axes, which changes how the colors map to values. So if you really want to use imagesc() then you have to omit the unused values from the legend.
You might be wondering why you need to generate surf() in order to put entries into the legend. This is because you can only give one legend per graphics object, and the entire imagesc(A) only generates one graphics object -- so to generate 6 legends you have to generate a minimum of 5 other graphics objects. It turns out that you cannot legend() an image() through, so even if you could get the color right for it, you need to generate all 6 graphics objects, one for each color. And if you do that generation of extra objects for values not present in your image, then you alter the color mapping for the image. And you are still left with the question about what the right color is for an entry that is before or after the end of the color map.
This is why I recommend against using imagesc() for your purpose. If you have 7 distinct values (0 to 6) then generate a colormap with 7 entries and image() the array of 0 to 6 values and colormap() the color map into place.
Siehe auch
Kategorien
Mehr zu Legend finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!