Can plot markers be specified in an array?

16 views (last 30 days)
I want to plot data from rows of a matrix using a separate marker for each row. I tried defining a string array and a cell array, like you can do with the legend command, but I got an error with both. It seems that the only way to do this is line by line, i.e., plot(x,row1,marker1,x,row2,marker2,...). Surely there is a better way.
  2 Comments
GS
GS on 1 Sep 2024
Thank you very much, Walter and Paul. This is what I was hoping for. I don't understand why they don't allow the plot command to accecpt the cell array as an argument in the first place, but this is the next best thing.
dpb
dpb on 1 Sep 2024
Edited: dpb on 1 Sep 2024
"... why they don't allow the plot command to accecpt the cell array as an argument"
What syntax specifically are thinking should work?
Perhaps the biggest reason for syntax being as it is is that plot <is an original member of MATLAB> and so predates all the niceties introduced later including cell arrays. Maintaining compatibility with existing code seriously restricts just how far away from the present syntax they can stray and still maintain the resulting code. plot() has been extended significantly with overloaded versions for the new data classes, etc., but the base argument syntax is simply not possible to revamp entirely

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 31 Aug 2024
h = plot(x, DATAMATRIX.');
set(h, {'Marker'}, CELL_ARRAY_OF_MARKERS(:))
where CELL_ARRAY_OF_MARKERS must be a cell string with the same number of entries as the number of rows in DATAMATRIX
Notice that DATAMATRIX has to be transposed in the plot call: the rule is that columns of data become individual lines.
  1 Comment
Paul
Paul on 31 Aug 2024
plot is smart enough to make each row of DATAMATRIX an individual line if that's the only way to be consistent with the number of elements of vector x
CELL_ARRAY_OF_MARKERS = {'+','o','x'};
DATAMATRIX = rand(3,4);
x = 1:4;
h = plot(x,DATAMATRIX); % no need for transpose
set(h,{'Marker'},CELL_ARRAY_OF_MARKERS(:))

Sign in to comment.

More Answers (3)

dpb
dpb on 31 Aug 2024
Use the multiple-handle option with set; there are examples there.
NOTA BENE the property name and the properties must be passed as cell arrays, even when the property is just one value if the values aren't a single value. I called it a second time below to illustrate...
markers={'x';'+';'o'};
x=rand(5,3);
hL=plot(x);
set(hL,{'Marker'},markers)
set(hL,'Marker',markers)
Error using matlab.graphics.chart.primitive.Line/set
Error setting property 'Marker' of class 'Line':
Invalid enum value. Use one of these values: '+' | 'o' | '*' | '.' | 'x' | 'square' | 'diamond' | 'v' | '^' | '>' | '<' | 'pentagram' | 'hexagram' | '|' | '_' | 'none'.
The alternative way is that one can loop over the variables and pass the property value from an array as well; that way means don't forget to set hold on to not erase the initial lines with the subsequent ones in the loop.

Star Strider
Star Strider on 31 Aug 2024
Both of those are possible (with the correct referencing), however I usually use a character array.
Try this —
marker = 'ox+p|sd';
x = 0:10;
y = randn(numel(marker), numel(x));
figure
plot(x,y(1,:),marker(1), x,y(2,:),marker(2), x,y(3,:),marker(3), x,y(4,:),marker(4), x,y(5,:),marker(5), x,y(6,:),marker(6), x,y(7,:),marker(7))
grid
figure
plot(x,y(1,:),['-',marker(1)], x,y(2,:),['-',marker(2)], x,y(3,:),['-',marker(3)], x,y(4,:),['-',marker(4)], x,y(5,:),['-',marker(5)], x,y(6,:),['-',marker(6)], x,y(7,:),['--',marker(7)])
grid
figure
hold on
for k = 1:numel(marker)
plot(x, y(k,:), '-', 'Marker',marker(k), 'DisplayName',"Marker "+string(marker(k)))
end
hold off
grid
ylim([min(ylim) max(ylim)*1.5])
legend('Location','best')
.
  14 Comments
dpb
dpb on 1 Sep 2024
Edited: dpb on 2 Sep 2024
Slick, Walter! I shoulda' thought of that years ago...use the feature frequently at the command line...so we can shorten the functional form significantly...
function markers=getplotmarkers()
% return list of allowable plot() markers as cellstr array
hF=figure('Visible','off'); % create figure, no see'um distraction
hAx=axes(hF); % and an axes in the specific figure for sure
hL=plot(hAx,nan); % a dummy line handle in that axes
markers=set(hL,'Marker'); % set w/o value returns available list if enumerated
delete(hL); delete(hAx); close(hF); % clean up after oneself
end
dpb
dpb on 1 Sep 2024
@Steven Lord -- Actually, I was thinking of only via the line 'Marker','char' form, not as part of a linestyle triad; would that not eliminate the conflict? The triads remain as they are being required to be one of the accepted character set for style, marker, color; just don't prevent/screen other characters from displaying what they are if explicitly set. Granted, the internal checking logic undoubtedly uses the same screeening, but we're talking hypothetical here... :)

Sign in to comment.


Umar
Umar on 1 Sep 2024

Hi @GS,

To address your query regarding, “ I want to plot data from rows of a matrix using a separate marker for each row. I tried defining a string array and a cell array, like you can do with the legend command, but I got an error with both. It seems that the only way to do this is line by line, i.e., plot(x,row1,marker1,x,row2,marker2,...). Surely there is a better way.”

Please see my response to your comments below.

First, create a sample data matrix dataMatrix with 5 rows and 10 columns filled with random values using rand(). I defined the variable x to represent the x-axis values, which correspond to the columns of the matrix. Then, name a cell array as markers containing different marker styles: circles, squares, triangles, diamonds, and crosses which will allow to assign a unique marker to each row of the matrix. Then, initiate a new figure and use hold on to ensure that all plots are displayed on the same graph without overwriting previous plots. Loop through rows by iteration row of the dataMatrix. Inside the loop, call the plot() function to plot the current row against the x-values, using the corresponding marker from the markers array and set the DisplayPropertyName to label each row for the legend. After the loop, call hold off to stop adding to the current plot. Then, label the axes, set a title for the plot, and display the legend using legend show and use grid on to enhance the readability of the plot.

Please see attached.

If you have any further questions, please let us know.

Categories

Find more on Data Distribution Plots in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!