How can I plot professional quality graphs in matlab? [closed] - matlab

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
The default graphs produced from matlab are very different from what I see in books. For example the image below looks visually pleasing. Can I change default settings of matlab to mimic this graphing style?

This question will refrain from lecturing the OP on best practices for graphics and simply attempt to answer the question as asked. I personally concur with a few of the concerns raised but leave it to the OP to seek out resources on data visualization and graphical aesthetics. (For the record, I'm not a fan of the chart.)
Resources:
The MATLAB Plot Gallery depicts a range of plots and adjustments that may help you. For high quality, professional looking graphs, scroll down to the Advanced Plots to see source code and the resulting figures.
Graphical overview of the Types of MATLAB Plots available.
You can also make a basic plot then use MATLAB's Plot Editor to customize the properties through the graphical interface. When done, click File-->Generate Code and you'll see one possible way to code that graph. This is helpful when you know how to do something through the interface but want to script it in the future.
Examples with code for Publication Quality Plots with Matlab
Mathworks blog on Making Pretty Graphs
Another example on Creating high-quality graphics in MATLAB for papers and presentations
I realize some of these links may eventually expire. Please feel free to comment if they do
Example:
I'm no expert. I learned everything in this answer from looking at the documentation, plot source code, and playing with the properties for the various plot components.
% Functions of Interest % MATLAB 2018a
fh=#(x) a + a*sin(b*x) + 1-exp(-b*x);
gh=#(x) a + (a/b)*cos(c*x);
a = 20;
b = .3;
c = .2;
% Plot
X = (0:.01:25)';
figure, hold on
p(1) = plot(X,fh(X),'r-','DisplayName','Excitation')
p(2) = plot(X,gh(X),'b-','DisplayName','Recovery')
% legend('show') % Optional legend (omitted here since we're adding text)
xlabel('X')
ylabel('Y')
title('Particle Displacement')
% Options
ha = gca;
box on
grid on
ylim([-80 100])
set(ha,'GridLineStyle','--') % use ':' for dots
t(1) = text(3.5,80,'excitation')
t(2) = text(12,20,'recovery')
for k = 1:2
p(k).LineWidth = 2.2;
t(k).FontWeight = 'bold';
t(k).FontSize = 12;
t(k).FontName = 'Arial';
end

Create a function which takes a matrix of data where each row represents a signal that you want to plot.
Define some styles you want to use for plotting. In your example plot, the first two would be 'bo' and 'rx'. Just iterate over your rows and plot each row with a different style followed by the command "hold on;"
function fancyplot(xaxis, matrix)
figure;
style = {'bo', 'rx', 'k.'}; # and so on
for r = 1:size(matrix, 1)
plot(xaxis, matrix(r,:), style{r});
hold on;
end
end
Write another script which you execute right after you plot or add it to the function above. In this script use the the following methods to control the limits of the axis
xlim
ylim
Set them to the min/max values of the data you plotted.
To add text to your plots use the Text command.
If you want to use these plots in publications be mindful of the fact that most publications are black and white and your graphs should be distinguishable event if they are not colored (I doubt the ones above would be). I always believed doing all formatting in code is a good idea without the manual tinkering around. Otherwise you might figure out that you have to update all 8 plots in your publication at 4 am shortly before you need to submit your paper. If you run some simulations and all formatting is in code you can simply execute your formatting scripts and save the plots automatically how to save a picture from code, preferably to the eps format.

Related

Efficient computation and redoing graphics actions

Are there any general guidelines on how Matlab handles graphics-based commands that ultimately result in no action being taken? A simple illustrative example--note the actual computational cost here is quite negligible:
fig=figure;
ax=axes;
for i=1:10
data=myFunction(i) %e.g. rand(i)
plot(data)
hold(ax,'on') %perform this repeatedly even though it's only needed once
end
versus:
fig=figure;
ax=axes;
for i=1:10
data=myFunction(i) %e.g. rand(i)
plot(data)
if ~ishold(ax)
hold(ax,'on') %perform this only if it is needed
end
end
If Matlab internally determines whether the hold(ax,'on') command is needed before actually doing it, then presumably the computational cost is similar or lower for the first form. The coding is also simpler to implement and read. But, if the action is carried out in full, then there are cases where it would be better, from a computational cost standpoint, to use the second form.
It's worth noting that the definition of "no action" here is deliberately vague, there's a lot of nuance here. For instance, it's easy to create an example where Matlab must perform some level of computation before it can evaluate whether the graphics command would have no effect. For instance, in colormap(myColormapFunction), Matlab would have to call myColormapFunction in order to evaluate whether what it returns is the same as the existing plot's CData property. Thanks.
As far as I know, there are no official guidelines on how "no action" commands are handled by the built-in MATLAB functions. Meanwhile, MathWorks does provide guidelines for optimizing graphics performance; which I feel, is a much more important thing to consider.
Graphics Performance Documentation Page
Now I apologize in advance if the following section doesn't answer your question. But if you are truly curious about the behind the scenes and real-world performance, you should use the provided Code Profiling Tool, and built-in timing functions.
With that said, the next section is about optimizing graphics performance in general.
For example, in the code you've provided, I would strongly recommend against putting hold and plot in the for-loop to begin with. From my experience, these are never necessary and can be optimized away.
Here, I'm guessing that you are trying to animate MATLAB plots; in which case, try updating the plot markers instead of using the plot function. For example:
figure
% Plot an empty plot with placeholder values (NaNs) the size of your data
% Save handle to plot object as `h`
h = plot( nan(size(data)) );
for i = 1:10
[Xdata, Ydata] = MyFunction(...);
% Update your plot markers with the handle update method
h.XData = Xdata;
h.YData = Ydata;
drawnow % drawnow to see animation
end
In this case, I don't even need to use the hold function, since I'm just updating the same plot, which is much faster.
Even if your function is outputting new data series, and you want to plot them on top of the old data series, you can use the same trick; it will only require you to pre-allocate the plot handles and data arrays. (Which, honestly is a good programming practice in general.)
figure
hold on % Hold the plot now
N = 100; % Number of data series you expect to have
H = cell(N,1); % Preallocate N Cells for all the plot handles
for i = 1:N
% Save plot handles to cell array in a loop, if you have so many series
H{i} = plot ( nan(size(data)) );
end
% Your iterative function calls
for t = 1:100
...
% Iteratively update all plot handles with a syntax like this
% (Not entirely sure, this is off the top of my head)
for i = 1:N
H{i}.XData = newX;
H{i}.YData = newY;
end
end

Manually pid design on Matlab

Good morning.
I am trying to design a PD controller manually and i wanted to be able to have a plot with parameters on which i can change their values live and see their result on plot. I want to emphasize again that i want to do the design by manualy changing Pi and PD parameters and not automatically via matlab pid designer.(The question is more matlab affiliated).
Sorry for my bad English.
Thanks in advance
(My code follows):
clear all;
clc;
syms s;
K=1;
num = 4500*K;
den = sym2poly(s^2+361.7*s);
G=tf(num,den);
H=1;
%%
Kp=2;
Ki=0;
Kd=0;
C=pid(Kp,Ki,Kd,0);
T=feedback(C*G,H);
step(T);
You can make a simple matlab GUI for that, with textboxes or sliders to representing your gains and an axes object to hold your plot. Than in the callback functions of the textboxes/sliders you just create your system and controller based on the Value properties of the textbox/sliders, simulate the response and plot it in the axes object.
Here you can find some tutorials for matlab guis

Plot two figures on the same figure using subplot [duplicate]

This question already has an answer here:
How does subplot work and what is the difference between subplot(121) and subplot(1,2,1) in MATLAB?
(1 answer)
Closed 8 years ago.
I am trying to plot the following using subplot how can I do that? Thank you
[n,wc]= buttord(Wp,Ws,Rp,Rs);
[z,p,k]=butter(n,wc);
sos = zp2sos(z,p,k);
freqz(sos) ;
grpdelay(sos) ;
Note that this is non-trivial since freqz yields a subplot already.
The following would work if the functions you are using plotted one figure each: call subplot right before each function that produces a graphic output. It is kind of straightforward from the manual, subplot(m,n,p) splits the figure into a grid of m x n graphics and draws the p-th one. However, as pointed by #hbaderts, freqz produces a subplot of its own, so you would need to rearrange it to include the upcoming output of grpdelay.
This is how you could do it, as per the workaround proposed in this thread (see it for the more general solution).
freqz(sos);
h = get(gcf, 'children');
fig2=figure;
figure(fig2)
g=subplot(3,1,1)
set(h(1), 'pos', get(g, 'pos'))
figure(fig2)
g=subplot(3,1,2)
set(h(2), 'pos', get(g, 'pos'))
close
g=subplot(3,1,3)
grpdelay(sos)
Probably the easiest solution is calculating the frequency response with freqz and plotting it with freqzplot. This is not the best solution because freqzplot is obsolete. A better solution would be to manually create the plots (e.g. 20*log10(abs(h))).
[h,w] = freqz(sos);
subplot(2,2,1);
freqzplot(h,w,'mag');
subplot(2,2,3);
freqzplot(h,w,'phase');
subplot(2,2,[2,4]);
grpdelay(sos);

MATLAB: Stacking .figs

I'm currently working on a study about fuel consumption. I have multiple .fig files that shows the trend of fuel consumption in L/100 Km versus Time. I have multiple cases showing the behavior of the plot under different conditions, and I wan't to show the differences between them. An example of the plot is shown below:
Is there anyway to stack plots from different .fig files in 1 .fig file?
Ideally, you'd want to generate those different plots using subplot.
Your exact question has been answered by ZiV in the mathworks forums:
One way to do this is to extract xdata and ydata from existing
figures, then re-plot these data in a new figure window as desired.
For example,
open('gugu.fig');
h_gugu=get(gca,'Children');
x_gugu=get(h_gugu,'XData');
y_gugu=get(h_gugu,'YData');
open('lulu.fig');
h_lulu=get(gca,'Children');
x_lulu=get(h_lulu,'XData');
y_lulu=get(h_lulu,'YData');
figure
subplot(121)
plot(x_gugu,y_gugu);
subplot(122)
plot(x_lulu,y_lulu)
saveas(gcf,'gugululu','fig')

Plotting multiple rose diagrams from different length lines

I have a text file with length and orientation of lines. I wish to plot rose diagrams of the orientations at length intervals of 2000m. My lengths go from 98m to 18000m. I do not use MATLAB often - only for very simple things such as plotting a rose diagram of the entire region. I am really lost when it comes to loops.
This is the what I have for the entire region. But I want it broken up into 10 plots. I can do this piece by piece but that will take me quite a while since I have to do this for several text files.
length=faults(:,4);
theta=faults(:,3);
radians=pi*theta/180;
rose (radians,60);
view(90,-90)
Thanks heaps!
EDIT: To better clarify: I wish to extract lines between 0-2000, 2000-4000. 4000-6000, etc. And for each of these intervals plot the orientation. Thanks
The best approach would be to use a for loop, see Mathwork's documentation on Flow Control. I'm not sure what your faults variable is, so I cannot give a complete example. Also, what do you need the variable length for? Anyway, this is roughly how you could proceed with the for loop:
thetas = ...; % matrix of thetas
for i = 1:size(thetas,2)
theta = thetas(:,i);
radians=pi*theta/180;
rose (radians,60);
end