function [filepath] = exportFig(filepath, args)
% exportFig - Function to save figure in many different formats
%
% Syntax: exportFig(filepath, args)
%
% Inputs:
% - filepath - path to file to export exportation (with or without extension)
% - args:
% - fig - Save fig file (default: false)
% - pdf - Save pdf file (default: true)
% - eps - Save eps file (default: false)
% - png - Save png file (default: true)
% - svg - Save svg file (default: false)
% - width -
% - height -
arguments
filepath
args.fig (1,1) logical {mustBeNumericOrLogical} = false
args.pdf (1,1) logical {mustBeNumericOrLogical} = true
args.png (1,1) logical {mustBeNumericOrLogical} = true
args.eps (1,1) logical {mustBeNumericOrLogical} = false
args.svg (1,1) logical {mustBeNumericOrLogical} = false
args.width = 'normal'
args.height = 'normal'
end
filepath_split = strsplit(filepath, '.');
if length(filepath_split) > 1
filepath = filepath_split{1};
end
- width-height
- first part (width): normal, full, half
- second part (height): normal, short, tall
We put here a negative value because when a positive value, the output result might be cropped out.
pos = [-10 -10];
Width sizes.
if strcmp(args.width, 'normal')
pos = [pos, 800];
elseif strcmp(args.width, 'wide')
pos = [pos, 900];
elseif strcmp(args.width, 'full')
pos = [pos, 1200];
elseif strcmp(args.width, 'half')
pos = [pos, 650];
elseif strcmp(args.width, 'third')
pos = [pos, 400];
elseif isnumeric(args.width)
pos = [pos, args.width];
else
pos = [pos, 800];
end
Height sizes.
if strcmp(args.height, 'normal')
pos = [pos, 500];
elseif strcmp(args.height, 'tall')
pos = [pos, 800];
elseif strcmp(args.height, 'full')
pos = [pos, 1000];
elseif strcmp(args.height, 'short')
pos = [pos, 400];
elseif strcmp(args.height, 'tiny')
pos = [pos, 300];
elseif isnumeric(args.height)
pos = [pos, args.height];
else
pos = [pos, 500];
end
Hide the figure so that i3
doesn’t interact with it during exports.
f = gcf;
set(f, 'visible', 'off');
Set wanted size.
set(f,'pos', pos);
if args.pdf || args.svg
exportgraphics(f, sprintf('%s.pdf', filepath), 'BackgroundColor', 'none', 'ContentType', 'vector');
end
if args.png
try
system(sprintf('pdftocairo -png -transp -singlefile %s.pdf %s >/dev/null 2>&1', filepath, filepath));
catch
warning('pdftocario command has failed. Using exportgraphics instead.');
exportgraphics(f, sprintf('%s.png', filepath));
end
end
if args.eps
exportgraphics(f, sprintf('%s.eps', filepath), 'BackgroundColor', 'none');
end
if args.svg
system(sprintf('pdftocairo -svg %s.pdf %s.svg >/dev/null 2>&1', filepath, filepath));
if ~args.pdf
system(sprintf('rm %s.pdf', filepath));
end
end
if args.fig
saveas(f, filepath, 'fig');
end
Show the figure again
set(f, 'visible', 'on');
End of function
filepath = [filepath, '.png'];
end
function mustBeWidth(arg)
if any(mustBeMember(arg,{'normal', 'wide', 'full', 'half', 'third'}) || mustBePositive(str2num(arg)))
error('Width is wrongly specify')
end
end
function mustBeHeight(arg)
if any(mustBeMember(arg,{'normal', 'tall', 'full', 'short', 'tiny'}) || mustBePositive(str2num(arg)))
error('Height is wrongly specify')
end
end
function [] = bodeFig(systems, freqs, opts_param)
%% TODO - Make documentation
%% Default values for opts
opts = struct(...
'phase', false, ...
'ylabel', '' ...
);
%% Check if the frequency is specified
ni = nargin;
if ni == 2
if isstruct(freqs)
opts_param = freqs;
clear freqs;
else
opts_param = struct();
end
end
%% Populate opts with input parameters
if exist('opts_param','var')
for opt = fieldnames(opts_param)'
opts.(opt{1}) = opts_param.(opt{1});
end
end
%% Number of subplots
n_subplots = 1;
if opts.phase
n_subplots = 2;
end
%% Cell of transfer function to array of tf
systems_arr = tf(0)*zeros(length(systems), 1);
for i = 1:length(systems)
systems{i}.InputName = {};
systems{i}.OutputName = {};
systems_arr(i) = tf(systems{i});
end
%% Compute the frequency response
bode_opts = bodeoptions;
bode_opts.FreqUnits = 'Hz';
bode_opts.PhaseWrapping = 'on';
if ~exist('freqs', 'var')
[resp,freqs] = freqresp(systems_arr);
freqs = freqs/(2*pi);
else
[resp,~] = freqresp(systems_arr, freqs, 'Hz');
end
resp_mag = abs(resp);
resp_phase = 180/pi*angle(resp);
%% Plot
figure;
%% Phase
if opts.phase
ax2 = subplot(n_subplots,1,2);
hold on;
for i = 1:length(systems)
plot(freqs, mod(180+resp_phase(i, :), 360)-180);
end
set(gca,'xscale','log');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
end
%% Amplitude
ax1 = subplot(n_subplots,1,1);
hold on;
for i = 1:length(systems)
plot(freqs, resp_mag(i, :));
end
set(gca,'xscale','log'); set(gca,'yscale','log');
if length(opts.ylabel) > 1
ylabel(opts.ylabel);
else
ylabel('Amplitude');
end
if ~opts.phase
xlabel('Frequency [Hz]');
else
set(ax1,'XTickLabel',[]);
end
hold off;
%% Link X-axis
if opts.phase
linkaxes([ax1, ax2], 'x');
end
xlim([freqs(1), freqs(end)]);
end
function [] = endOfCode()
load('gong', 'Fs', 'y');
sound(0.5*y, Fs);
end
function varargout = matSplit(A,dim)
%MATSPLIT Split matrix elements into separate variables.
% VARARGOUT = MATSPLIT(A) returns each element of the array A in a
% separate variable defined by VARARGOUT.
%
% VARARGOUT = MATSPLIT(A,DIM) only splits the matrix in one dimension. If
% DIM=1, each column vector is assigned to an output variable. If
% DIM=2, each row vector is assigned to an output variable.
if nargin==1
varargout = num2cell(A);
else
varargout = num2cell(A,dim);
end
end
function [] = openSisotool(G)
% mycustomcontrolsysdesignerfcn(G)
%
% Creates the following Control System Designer session:
% 1) Configuration 4 with the plant specified by G
% 2) Root locus and bode editors for the outer-loop
% 3) Bode editor for the inner-loop.
% Copyright 1986-2005 The MathWorks, Inc.
% Create initialization object with configuration 4
s = sisoinit(1);
% Set the value of the plant
s.G.Value = G;
% Specify the editors for the Open-Loop Responses
s.OL1.View = {'rlocus','bode'};
controlSystemDesigner(s)
end
%% Default plot colors
c1 = [ 0 0.4470 0.7410]; % Blue
c2 = [0.8500 0.3250 0.0980]; % Orange
c3 = [0.9290 0.6940 0.1250]; % Yellow
c4 = [0.4940 0.1840 0.5560]; % Purple
c5 = [0.4660 0.6740 0.1880]; % Green
c6 = [0.3010 0.7450 0.9330]; % Light Blue
c7 = [0.6350 0.0780 0.1840]; % Red
function [G_string] = tf2string(G)
G = tf(G);
syms s;
sym_num=poly2sym(G.num{:},s);
sym_num=vpa(sym_num, 4);
char_num=char(sym_num);
sym_den=poly2sym(G.den{:},s);
sym_den=vpa(sym_den, 4);
char_den=char(sym_den);
G_string = ['(', char_num, ')/(', char_den, ')'];
end
function [G_string] = zpk2latex(G)
[z, p, k] = zpkdata(G);
C_gain = sprintf('%.1e ', k);
C_num = '';
for i = 1:length(z{1})
C_num = horzcat(C_num, '(s');
if imag(z{1}(i)) == 0
C_num = horzcat(C_num, sprintf('%+.1e', -z{1}(i)));
else
C_num = horzcat(C_num, sprintf('-(%.1e%+.1e i)', real(z{1}(i)), imag(z{1}(i))));
end
C_num = horzcat(C_num, ')');
end
C_den = '';
for i = 1:length(p{1})
C_den = horzcat(C_den, '(s');
if imag(p{1}(i)) == 0
C_den = horzcat(C_den, sprintf('%+.1e', -p{1}(i)));
else
C_den = horzcat(C_den, sprintf('-(%.1e%+.1e i)', real(p{1}(i)), imag(p{1}(i))));
end
C_den = horzcat(C_den, ')');
end
C_size = max(length(C_num), length(C_den));
G_string = [C_gain, '\frac{', C_num, '}{', C_den, '}'];
end
function [G_string] = zpk2string(G)
[z, p, k] = zpkdata(G);
C_gain = sprintf('%+.1e ', k);
C_num = repmat(' ', 1, length(C_gain)+1);
for i = 1:length(z{1})
C_num = horzcat(C_num, '(s');
if imag(z{1}(i)) == 0
C_num = horzcat(C_num, sprintf('%+.1e', -z{1}(i)));
else
C_num = horzcat(C_num, sprintf('-(%.1e%+.1e i)', real(z{1}(i)), imag(z{1}(i))));
end
C_num = horzcat(C_num, ')');
end
C_den = repmat(' ', 1, length(C_gain)+1);
for i = 1:length(p{1})
C_den = horzcat(C_den, '(s');
if imag(p{1}(i)) == 0
C_den = horzcat(C_den, sprintf('%+.1e', -p{1}(i)));
else
C_den = horzcat(C_den, sprintf('-(%.1e%+.1e i)', real(p{1}(i)), imag(p{1}(i))));
end
C_den = horzcat(C_den, ')');
end
C_size = max(length(C_num), length(C_den));
C_frac = repmat('-', 1, C_size+1);
G_string = [C_num, '\n', C_gain, C_frac, '\n', C_den];
end
function [Gp] = flipRphZeros(G)
% flipRphZeros -
%
% Syntax: [Gp] = flipRphZeros(G)
%
% Inputs:
% - in_data -
%
% Outputs:
% - in_data -
[z, p, k] = zpkdata(G);
z{1}(real(z{1}) > 0) = -real(z{1}(real(z{1}) > 0)) + imag(z{1}(real(z{1}) > 0));
Gp = zpk(z, p, k);
end
function [Gp] = flipRphPoles(G)
% flipRphPoles -
%
% Syntax: [Gp] = flipRphPoles(G)
%
% Inputs:
% - in_data -
%
% Outputs:
% - in_data -
[z, p, k] = zpkdata(G);
p{1}(real(p{1}) > 0) = -real(p{1}(real(p{1}) > 0)) + imag(p{1}(real(p{1}) > 0));
Gp = zpk(z, p, k);
end