Is that possible to assemble several options and pass to the plot function in matlab - matlab

I am using MATLAB to plot several figures and hope these figure use the same plot options, it looks something like this:
N = 20;
Fs = 200;
t = (0:N-1)/Fs;
x = sin(2*pi*10*t);
y = cos(2*pi*20*t);
z = x + y;
figure(1),clf;
subplot(311);
plot(t, x, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
subplot(312);
plot(t, y, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
subplot(313);
plot(t, z, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
You can see the plot options are exactly the same. If I want to change the style, I have to change each of them. Is that possible assemble/group them together and pass them to the plot function?
I have tried to put them in a cell like this
plotOptions = {'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3};
It doesn't work. The reason might be the plot functions would take the plotOptions as one paramter and thus failed to parse it.

Using a cell with the options was already a good approach. Just use {:}, as below:
opt = {'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3};
figure(1),clf;
subplot(311);
plot(t, x, opt{:});
Then, each element of the cell is evaluated as single argument.

Solution with unique plotting function:
subplot(312);
myplot(t,y)
Save myplot function as a separate m-file.
function myplot(t,x)
plot(t, x, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
end

The cell answer is good, another option is to set the arg value to be a variable:
faceColor = 'b';
lineWidth = 3;
figure(1),clf;
subplot(311);
plot(t, x, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
subplot(312);
plot(t, y, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
subplot(313);
plot(t, z, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);

A very clean alternative approach would be to keep the plot command as simple as possible and manipulate the handles afterwards.
opts = {'Color','red','MarkerFaceColor', 'b', 'LineWidth',3};
h(1) = plot(t, x);
grid on;
subplot(312);
h(2) = plot(t, y);
grid on;
subplot(313);
h(3) = plot(t, z);
grid on;
arrayfun(#(x) set(x,opts{:}),h)
The advantage over the indeed neat approach by Nemesis is, that in case you have multiple sets of properties, like:
opts.slimRed = {'Color','red','MarkerFaceColor', 'b', 'LineWidth',1};
opts.fatBlue = {'Color','blue','MarkerFaceColor', 'b', 'LineWidth',5};
and you want to exchange them, you just need to modify one variable
arrayfun(#(x) set(x,opts.fatBlue{:}),h)
to change the appearance of a whole set of handles h.

Related

Matlab: How to save multiple variable points from mouse click (with 'ButtonDownFcn') from a plot into the workspace?

I have a figure with some vertical lines added, as such:
figure
x = rand(1,41);
y = 1:41;
H(1)= plot(x,y,'r.');
H(2)= line([x(21) x(21)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(3)= line([x(3) x(3)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
H(4)= line([x(15) x(15)],[0 max(y)], 'LineWidth', 2, 'Color', 'k');
I would like to be able to click on the lines with the mouse button, and store each of the clicked line index.
The following script works but I don't know how to store each index in an array. The 'IndInWorkSpace' keeps changing for each click.
set(H, 'ButtonDownFcn', {#LineSelected, H})
function [indices] = LineSelected(ObjectH, H)
set(ObjectH, 'LineWidth', 4);
set(H(H ~= ObjectH), 'LineWidth', 2);
% Get x and y data of the highlighted lines
ind = ObjectH.XData
assignin('base','IndInWorkSpace',ind);
end
Any help will be much appreciated! Thank you!
An easy fix is to first check if there was already an index found in the base workspace. If there already is a variable IndInWorkSpace, append to it, otherwise assign a new variable.
function LineSelected(ObjectH, H)
set(ObjectH, 'LineWidth', 4);
set(H(H ~= ObjectH), 'LineWidth', 2);
% Get x and y data of the highlighted lines
ind = ObjectH.XData;
if evalin('base','exist(''IndInWorkSpace'',''var'')')
indArray = evalin('base','IndInWorkSpace');
indArray(end+1) = ind;
else
indArray = ind;
end
assignin('base', 'IndInWorkSpace', indArray);
end

How can I adjust line width for individual lines in a combined plot?

When I adjust line width for this type of plot it works.
plot(x1,y1, 'm','Linewidth',1)
hold on
plot(x2,y2, 'b','Linewidth',2)
hold on
plot(x3,y3, 'r','Linewidth',3)
hold on
plot(x4,y4, 'c','Linewidth',4)
hold on
plot(x5,y5, 'o','Linewidth',5)
But not when I do this.
plot(x1, y1, 'm','Linewidth',1,x2, y2, 'b','Linewidth',2,x3, y3, 'r','Linewidth',3,x4, y4, 'c','Linewidth',4,x5, y5, 'o','Linewidth',5);
I get an error.
Is it possible to adjust line width for a combined plot?
Is it possible to adjust line width for a combined plot?
No (well yes but not in a cleaner way).
You can adjust the parameters for all of them together if you want a single line. If you want control over the appearance of each of them, you will need to do separate plots.
You can do it accessing the properties, but I suspect that is just longer and less clear, so not sure if it is really the right solution.
h=plot(x1, y1, x2, y2, ...);
h(1).LineWidth=1;
h(2).LineWidth=2;
...
An alternate approach that is more scalable for greater numbers of plots and/or extra properties uses arrayfun. Basically, if you set up the data for all your plots in arrays, you can then plot all data with only one line of code
% set up the data and all plot attributes
x = {x1, x2, x3, x4, x5};
y = {y1, y2, y3, y4, y5};
styles = ['m', 'b', 'r', 'c', 'o'];
widths = [1, 2, 3, 4, 5];
% setup figure
figure
ax = axes('NextPlot','add'); % like calling hold on
% plot all elements
% equivalent to a for loop: for i = 1:length(x)
arrayfun(#(i) plot(ax, x{i}, y{i}, styles(i), 'linewidth', widths(i)), 1:length(x));
I don't like using hold since it is hard to know if it is on or off when you do the next plot. I like to use plot for the first line and line for subsequent lines like this:
plot(x1, y1, 'm', 'linewidth', 1)
line(x2, y2, 'color', 'b', 'linewidth', 2)
line(x3, y3, 'color', 'r', 'linewidth', 3)
line(x4, y4, 'color', 'c', 'linewidth', 4)
line(x5, y5, 'color', 'o', 'linewidth', 5)

multiple plot in one plot in MATLAB using hold on/off statements

How can I fix this so that it would show all three plots in one plot?
I followed the instruction in this SO answer but didn't work out: https://stackoverflow.com/a/8773571/2414957
figure;
t = -pi:0.01:pi;
a = sin(t);
plot(t, a, 'r', 'DisplayName', 'a'); hold on;
fhat = (21./(8*pi.^10))*(33*pi.^4-3465*pi.^2+31185)*t.^2 +(3750*pi.^4 -30*pi.^6 -34650*pi.^2)*t.^3 +(5*pi^8-765*pi.^6+7425*pi.^4)*t;
plot(t, fhat, 'c', 'DisplayName', 'fhat');
hold on;
p = t - (t.^3)/factorial(3) + (t.^5)/factorial(5);
plot(t, p, 'b', 'DisplayName', 'p');
hold on;
title('Sine plot by sin(t)');
xlabel('t');
ylabel('sin(t)');
legend('show');
The 3 plots have variant range, therefore, you need to make normalization to plot all functions on the same space
figure;
t = -pi:0.01:pi;
a = sin(t);p = t - (t.^3)/factorial(3) + (t.^5)/factorial(5);
fhat = (21./(8*pi.^10))*(33*pi.^4-3465*pi.^2+31185)*t.^2 +(3750*pi.^4 -30*pi.^6 -34650*pi.^2)*t.^3 +(5*pi^8-765*pi.^6+7425*pi.^4)*t;
%display
plot(t, p/norm(p), 'b', 'DisplayName', 'p');
hold on; %you need only one 'hold on'
plot(t, a/norm(a), 'r', 'DisplayName', 'a');
plot(t, fhat/norm(fhat), 'c', 'DisplayName', 'fhat');
title('Sine plot by sin(t)');
xlabel('t');
ylabel('sin(t)');
legend('show');
You are plotting all three functions. What happens is that p is drawn over a. They are both very small compared to that, and therefore fall on the same pixels on your screen.
To verify this you can zoom in:
set(gca,'ylim',[-1.5,1.5])
Alternatively, plot p using dots or dashes, so the other line shows through in between:
figure;
t = -pi:0.01:pi;
a = sin(t);
plot(t, a, 'r', 'DisplayName', 'a'); hold on;
fhat = (21./(8*pi.^10))*(33*pi.^4-3465*pi.^2+31185)*t.^2 +(3750*pi.^4 -30*pi.^6 -34650*pi.^2)*t.^3 +(5*pi^8-765*pi.^6+7425*pi.^4)*t;
plot(t, fhat, 'c', 'DisplayName', 'fhat');
hold on;
p = t - (t.^3)/factorial(3) + (t.^5)/factorial(5);
plot(t, p, 'b--', 'DisplayName', 'p'); % Note the 'b--' line format here!
hold on;
title('Sine plot by sin(t)');
xlabel('t');
ylabel('sin(t)');
legend('show');

two graphs in one plot matlab

I want to plot two data (x1,y1)=(x,y) which x and y determine some points in space and (xx1,yy1)=(12,12) in the same plot in Matlab. I used below code but there is an error and it doesn't wor. Could anyone help?
h = plot(x, y, '.g', 'MarkerSize', 10,12,12,'.r', 'MarkerSize', 15);
The complete code is as below.. I want to show a red big dot at the center of the video:
clear all
close all
l=25;
v=0.05;
dt=1;
r=1;
rr=25;
noise=(2.*pi).*.05;
nn=100;
set(gcf, 'doublebuffer', 'on', 'Color', 'k');
set(gca, 'Visible', 'off');
axis([0 l 0 l])
axis('square')
hold on
vidObj = VideoWriter('vicchemo1.avi');
open(vidObj);
x=rand(nn,1).*l; %first possition
Just below h = plot(x, y, '.g', 'MarkerSize', 10); on line 46. Add the following code:
xc = xlim/2;
yc = ylim/2;
plot(xc(2), yc(2), '.r', 'MarkerSize', 15);
I do not know if I understood your question properly or not. Below lines of code plot the data on same figure:
plot(x, y, '.g', 'MarkerSize', 10)
hold
plot(12,12,'.r', 'MarkerSize', 15)
try something like this
hold on
plot(x, y, '.g', 'MarkerSize', 10)
plot(12,12,'.r', 'MarkerSize', 15)
hold off

mark point on figure

From this Matlab code :
a=[1:.001:5] ;
f=(1./a)-(a-1) ;
plot(a,f)
I want to mark the point when (f==0) on the figure, assuming the value of a is unknown and I should take it from the figure.
I want it to look like this:
Use the command 'text' http://www.mathworks.com/help/matlab/ref/text.html as follows,
[~,idx] = find(abs(f)<1e-3);
text( a(idx(1)), f(idx(1)), 'here we touch/cut/cross x-axis')
You can use interp1 to find the point where f = 0;
a_for_f_equal_zero = interp1(f, a, 0);
line(a_for_f_equal_zero, 0, 'marker', 'o', 'color', 'r', 'linestyle', 'none')
x_lim = get(gca, 'XLim');
y_lim = get(gca, 'YLim');
line(a_for_f_equal_zero * [1,1], [y_lim(1), 0], 'color', 'k') % vertical line
line([x_lim(1), a_for_f_equal_zero], [0,0], 'color', 'k') % horizontal line