Generating dynamic legend without duplicates
6 次查看(过去 30 天)
显示 更早的评论
So, I have a number of datasets stored in two row vectors each, the first storing x-values and the second y-values of a number of points. At a particular point, where the x-value exceeds a certain value, I split both vectors in two, generating two smaller sub-datasets. Each of these two are then fitted with a logarithmic function and plotted. Both of these plots are supposed to share legend labels, color scheme and marker scheme. This process is then repeated multiple times. (Current code is a WIP, finished code is supposed to loop, code is blocked for demonstration purposes only.) To do this, I have attempted to use a solution like this one here. My issue is that using this code I have been unable to find a way to hide duplicated legends. I feel like I have not fully grasped the function of legend(gca,'off') and I am not confident enough in my MATLAB knowledge to know whether using legend('-DynamicLegend'); would be smart to use in this case.
I have included a demo of my code below:
% Clear old vars before run
clear
clc
% myPalette8 = []
myPalette16 = ["#2f4f4f" "#006400" "#bdb76b" "#4b0082" "#48d1cc" ...
"#ff0000" "#ffa500" "#ffff00" "#00ff00" "#00fa9a" "#0000ff" ...
"#d8bfd8" "#ff00ff" "#1e90ff" "#fa8072" "#ff1493"]
myPalette24 = ["#2f4f4f" "#556b2f" "#800000" "#483d8b" "#008000" ...
"#9acd32" "#00008b" "#daa520" "#8b008b" "#ff0000" "#ffff00" ...
"#7cfc00" "#40e0d0" "#00ff7f" "#00bfff" "#0000ff" "#d8bfd8" ...
"#ff7f50" "#ff00ff" "#1e90ff" "#db7093" "#ff1493" "#ee82ee" ...
"#ffe4b5"]
myPalette36 = ["#696969" "#c0c0c0" "#556b2f" "#a0522d" "#228b22" ...
"#808000" "#483d8b" "#008080" "#4682b4" "#9acd32" "#00008b" ...
"#32cd32" "#daa520" "#8fbc8f" "#8b008b" "#b03060" "#ff0000" ...
"#00ced1" "#ff8c00" "#7fff00" "#9400d3" "#00fa9a" "#dc143c" ...
"#0000ff" "#ff00ff" "#1e90ff" "#f0e68c" "#fa8072" "#ffff54" ...
"#dda0dd" "#ff1493" "#7b68ee" "#ee82ee" "#87cefa" "#7fffd4" ...
"#ffb6c1"]
mySelectedPalette = myPalette24
hold all
% Code Block 1
% Provide Data
FirstDataUnits = [1 11 20 49 67 86 101 104 108 111 115 119 123 127 ...
132 137 142 147 152 158 164 170 177 183 190 197 205 212 220 ...
228 236 244 253 262 270 279 288 297 306]
FirstDataValue = [179 181 182 183 185 186 187 189 190 191 192 194 ...
195 196 198 199 200 202 203 204 205 207 208 209 211 212 213 ...
215 216 217 218 220 221 222 224 225 226 228 229]
% Split input data into a section below trade excess threshold and one
% above the threshold
excess = 100
firstIndexOverExcess = find(FirstDataUnits>excess,1,'first')
% trimdata trims first values, latter part the end values
% Two row vectors are created and fed into a cell array
FirstDataUnitsSplit = {trimdata(FirstDataUnits,firstIndexOverExcess-1), FirstDataUnits(firstIndexOverExcess:end)}
% trimdata trims first values, creating two row vectors for unit cost
FirstDataValueSplit = {trimdata(FirstDataValue,firstIndexOverExcess-1), FirstDataValue(firstIndexOverExcess:end)}
for i = 1:2
% Plot both parts
DataFitOne = fit(transpose(FirstDataUnitsSplit{1,i}), transpose(FirstDataValueSplit{1,i}),'log')
DataPlotOne = plot(DataFitOne, FirstDataUnitsSplit{1,i}, FirstDataValueSplit{1,i})
% Optional: Plot confidence interval
%plot(heavyMachChicOpen300Units{1,i},predint(heavyMachChicOpen300Fit,heavyMachChicOpen300Units{1,i},0.95,'functional','on'),'m--')
DataPlotOne(1).Color = mySelectedPalette(9); % sth
DataPlotOne(1).Marker = '*'; % circle
DataPlotOne(2).Color = mySelectedPalette(10); % sth
legend(DataPlotOne, 'Data Points One', 'Fit Function One')
end
% Code Block 2
% Provide Data
SecondDataUnits = [1 101 230 307 323 341 360 381 404 429 457 ...
487 520 556 594 636 682 730 781 836 893 952 1014 1078 1142 1209 ...
1277 1345 1414 1483]
SecondDataValue = [125 126 127 129 130 131 133 134 135 137 ...
138 139 140 142 143 144 146 147 148 150 151 152 153 155 156 157 ...
159 160 161 163]
% Split input data into a section below trade excess threshold and one
% above the threshold
excess = 300
firstIndexOverExcess = find(SecondDataUnits>excess,1,'first')
% trimdata trims first values, latter part the end values
% Two row vectors are created and fed into a cell array
SecondDataUnitsSplit = {trimdata(SecondDataUnits,firstIndexOverExcess-1), SecondDataUnits(firstIndexOverExcess:end)}
% trimdata trims first values, creating two row vectors for unit cost
SecondDataValueSplit = {trimdata(SecondDataValue,firstIndexOverExcess-1), SecondDataValue(firstIndexOverExcess:end)}
for i = 1:2
% Plot both parts
DataFitTwo = fit(transpose(SecondDataUnitsSplit{1,i}), transpose(SecondDataValueSplit{1,i}),'log')
DataPlotTwo = plot(DataFitTwo, SecondDataUnitsSplit{1,i}, SecondDataValueSplit{1,i})
% Optional: Plot confidence interval
%plot(heavyMachChicOpen300Units{1,i},predint(heavyMachChicOpen300Fit,heavyMachChicOpen300Units{1,i},0.95,'functional','on'),'m--')
DataPlotTwo(1).Color = mySelectedPalette(11); % sth
DataPlotTwo(1).Marker = '*'; % circle
DataPlotTwo(2).Color = mySelectedPalette(12); % sth
legend(DataPlotTwo, 'Data Points Two', 'Fit Function Two')
end
% [MORE CODE BLOCKS LIKE ABOVE]
% legend(gca, 'off') is paired with the line directly below it.
% Essentially it turns the legend off (the line below turns it back on),
% which forces Matlab to refresh and display new legend changes.
legend(gca,'off');
legend('show');
0 个评论
回答(1 个)
Matt J
2025-4-27
编辑:Matt J
2025-4-27
One way:
load Inputs
mySelectedPalette = myPalette24;
% Code Block 1
% Split input data into a section below trade excess threshold and one
% above the threshold
excess = 100;
addLines(FirstDataUnits,FirstDataValue,excess, mySelectedPalette(9:10), ...
'Data Points One', 'Fit Function One');
% Code Block 2
excess = 300;
addLines(SecondDataUnits,SecondDataValue,excess, mySelectedPalette(11:12), ...
'Data Points Two', 'Fit Function Two');
legend(gca,'off');
legend('show');
function addLines(DataUnits,DataValue,excess, mySelectedPalette, varargin)
firstIndexOverExcess = find(DataUnits>excess,1,'first');
% trimdata trims first values, latter part the end values
% Two row vectors are created and fed into a cell array
DataUnitsSplit = {trimdata(DataUnits,firstIndexOverExcess-1), DataUnits(firstIndexOverExcess:end)};
% trimdata trims first values, creating two row vectors for unit cost
DataValueSplit = {trimdata(DataValue,firstIndexOverExcess-1), DataValue(firstIndexOverExcess:end)};
hold on
for i = 1:2
% Plot both parts
DataFit = fit(transpose(DataUnitsSplit{1,i}), transpose(DataValueSplit{1,i}),'log');
DataPlot = plot(DataFit, DataUnitsSplit{1,i}, DataValueSplit{1,i});
% Optional: Plot confidence interval
%plot(heavyMachChicOpen300Units{1,i},predint(heavyMachChicOpen300Fit,heavyMachChicOpen300Units{1,i},0.95,'functional','on'),'m--')
DataPlot(1).Color = mySelectedPalette(1); % sth
DataPlot(1).Marker = '*'; % circle
DataPlot(2).Color = mySelectedPalette(2); % sth
[DataPlot.DisplayName] = deal(varargin{:}) ;
if i>1
DataPlot(1).Annotation.LegendInformation.IconDisplayStyle = 'off'; % Hides from legend
DataPlot(2).Annotation.LegendInformation.IconDisplayStyle = 'off'; % Hides from legend
end
end
hold off
end
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!