MATLAB Answers

0

How to plot lines instead of symbols in loop

Asked by Benjamin on 15 Nov 2018
Latest activity Commented on by Benjamin on 15 Nov 2018
In the code below, it works fine. When I change
'-o'
to
'-'
, it does not plot anything, I am guessing the data gets deleted so it does not know what to connect to.
How can I plot with just a line and not symbols here?
filename = 'C:\PATH\file.xlsx';
S=struct;
for n=20:-1:1
A= xlsread(filename,sprintf('0.6%02d',n));
S(n).data=A;
end
fn = fieldnames(S);
names = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
point = {'0.601','0.602','0.603','0.604','0.605','0.606','0.607','0.608','0.609','0.610','0.611','0.612','0.613','0.614','0.615','0.616','0.617','0.618','0.619','0.620'};
for fig = 1:10:41
figure(fig)
ycolumn = fig;
for oloop = 1:1:8
xdata = 0.601;
subplot(3,3,oloop)
for k = 1:size(S,2)
thisS = S(k).data;
num_no_nans = sum( ~isnan(thisS(:,ycolumn)) ) ;
x = thisS(num_no_nans, 1);
y = thisS(num_no_nans, ycolumn+1);
fprintf('Printing field #%d.\n', k);
% semilogy(xdata, y,'-');
semilogy(xdata(k),y(k))
hold on
drawnow;
grid on;
xlim([0.600 0.621]);
xdata = xdata + 0.001;
end
xlabel('Density (g/cm^3)');
ylabel( sprintf('%s', names{oloop}));
ycolumn = ycolumn + 1;
hold on
end
end

  1 Comment

I deleted my answer so someone who knows better can solve the problem :)

Sign in to comment.

2 Answers

Answer by Adam Danz
on 15 Nov 2018
Edited by Adam Danz
on 15 Nov 2018
 Accepted Answer

The reason a line will not show but single markers will is because you're only plotting one point at a time within the loop. A line needs a minimum of 2 points. If you step through your code in debug mode, this would have been clear.
Plotting one point at a time is very inefficient and it doesn't look like that's needed. So I reorganized your code to make it more efficient and allow you to plot a line in addition to markers. Further efficiencies could be made but I wanted the updated code to be recognizable.
Instead of the plotting function residing in the k-loop, it now follows the k-loop. The k-loop merely collects the y-data. I also removed the hold, grid, and some other features from the k-loop since there's no need to run them every iteration. Some differences you'll notice is that all points are the same color now. The color wasn't intentionally set in your code and since the points are still in order along the x axis, there's no real need to color code them.
for fig = 1:10:41
figure(fig)
ycolumn = fig;
for oloop = 1:1:8
xdata = 0.601;
sh = subplot(3,3,oloop);
hold(sh, 'on')
grid(sh, 'on');
y = nan(1, size(S,2));
x = xdata : 0.001 : xdata + (0.001 * (size(S,2)-1));
for k = 1:size(S,2)
thisS = S(k).data;
num_no_nans = sum( ~isnan(thisS(:,ycolumn)) ) ;
y(k) = thisS(num_no_nans, ycolumn+1);
end
semilogy(x, y,'-o'); % <-- here's your line with markers
xlim([0.600 0.621]);
xlabel('Density (g/cm^3)');
ylabel( sprintf('%s', names{oloop}));
ycolumn = ycolumn + 1;
end
end

  1 Comment

Sign in to comment.


Answer by jonas
on 15 Nov 2018
Edited by jonas
on 15 Nov 2018

The problem is that you are plotting one data point at a time, which means that each point gets a separate handle and is thus not connected to the others. Some general advice:
  • prepare your data before plotting and then plot all data in one go, at least all data for each subplot.
  • personally I'd use a cell array for, S, instead of a struct
  • avoid nested for loops when possible, it makes the code really obnoxious to debug
I tried cleaning up the code for you but gave up halfway and made an ugly solution instead. Replace the inner loop with the below excerpt. The first point of each subplot is drawn using semilogy, which creates a handle. The remaining points are then added to the same line handle, thus connecting the points.
for k = 1:size(S,2)
thisS = S(k).data;
num_no_nans = sum( ~isnan(thisS(:,ycolumn)) ) ;
x = thisS(num_no_nans, 1);
y = thisS(num_no_nans, ycolumn+1);
fprintf('Printing field #%d.\n', k);
if k==1
h = semilogy(xdata, y,'-');
else
h.XData = [h.XData xdata];
h.YData = [h.YData y];
end
hold on
drawnow;
grid on;
xlim([0.600 0.621]);
xdata = xdata + 0.001;
end

  0 Comments

Sign in to comment.