[plotting] object way of editing plot properties

This commit is contained in:
Jan Grewe 2019-11-28 16:56:26 +01:00
parent 2e0b2a5239
commit 19983392c5
6 changed files with 152 additions and 95 deletions

View File

@ -1,10 +1,12 @@
time = 0.0:0.001:1.0;
y = sin(2 * pi * 2 .* time);
figure
hold on
set(gcf, 'Color', 'white', 'PaperUnit', 'centimeters', 'PaperSize', [4 4], ...
'PaperPosition', [0 0 4 4])
fig = figure();
fig.PaperUnits = 'centimeters';
fig.PaperSize = [4 4];
fig.PaperPosition = [0.0 0.0 4, 4];
fig.Color = 'white';
plot(time, y)
plot([0.0 1.0], [0.0 0.0], '--', 'color','k', 'linewidth', 0.75)

View File

@ -1,26 +1,40 @@
load('pyramidal_response.mat')
threshold = 20; % mV
hold on
hold on;
plot(time*1000.0, neuronal_data, 'color', [0.2 0.5 0.7], ...
'linewidth', 1., 'displayname', 'Membrane voltage')
'linewidth', 1., 'displayname', 'Membrane voltage');
plot(spikes*1000.0, ones(size(spikes)) .* threshold, 'r.', ...
'markersize', 15, 'displayname', 'Spike times')
'markersize', 15, 'displayname', 'Spike times');
line([time(1) time(end)], [threshold threshold], 'linestyle', '--', ...
'linewidth', 0.75, 'color', [0.5 0.5 0.5], 'displayname', 'Threshold')
'linewidth', 0.75, 'color', [0.5 0.5 0.5], 'displayname', 'Threshold');
xlabel('Time [ms]', 'fontname', 'times', 'fontsize', 11)
ylabel('Potential [mV]', 'fontname', 'times', 'fontsize', 11)
title('ELL pyramidal neuron', 'fontname', 'times', 'fontsize', 12)
ylim([0 40])
xlim([500 1700])
box('off')
l = legend(gca,'show');
set(l,'location','northeast', 'fontsize', 11, 'linewidth', 1.);
set(gca, 'xminortick','on','yminortick','on')
set(gca, 'tickdir','out', 'linewidth', 1.5, 'fontname', 'times', ...
'fontsize', 11)
set(gcf, 'paperunits', 'centimeters', 'papersize', [15 7]);
set(gcf, 'paperposition',[0.0 0.0 15, 7], 'color', 'white')
axes = gca();
axes.XLabel = 'Time [ms]';
axes.YLabel = 'Potential [mV]';
axes.Title = 'ELL pyramidal neuron';
axes.XLim = [[500 1700];
axes.YLim = [0 40];
axes.XMinorTick = 'on';
axes.YMinorTick = 'on';
axes.TickDir = 'out';
axes.LineWidth = 1.5;
axes.box('off')
saveas(gcf, 'spike_detection.pdf', 'pdf')
axes.FontName = 'Times';
axes.FontSize = 8;
axes.TitleFontSizeMultiplier = 1.5;
axes.LabelFontSizeMultiplier = 1.25;
l = legend(axes, 'show');
l.Location = "northeast";
l.FontSize = 11;
l.LineWidth = 1;
fig = gcf();
fig.PaperUnits = 'centimeters';
fig.PaperSize = [15, 7];
fig.PaperPosition = [0.0 0.0 15, 7];
fig.Color = 'white';
saveas(gcf, 'spike_detection.pdf', 'pdf')

View File

@ -11,8 +11,11 @@ err_upper_asym = prctile(asym_data, 75, 1);
err_lower_asym = prctile(asym_data, 25, 1);
fig = figure();
set(fig, 'paperunits', 'centimeters', 'papersize', [15 6.5], ...
'paperposition', [0.0 0.0 15, 6.5], 'color', 'white')
fig.PaperUnits = 'centimeters';
fig.PaperSize = [15 6.5];
fig.PaperPosition = [0.0 0.0 15, 6.5];
fig.Color = 'white';
subplot(1,3,1)
errorbar(x_data, avg_sym, err_sym, 'marker', 'o')
xlim([-.5, 6.5])

View File

@ -7,9 +7,11 @@ f_y = 1.5;
dt = 2*pi/500;
f = figure();
set(f, 'visible', 'off');
set(f, 'PaperUnits', 'centimeter', 'PaperSize', [2.5, 2.5], ...
'PaperPosition', [0, 0, 2.5, 2.5], 'Color', 'white')
f.Visible = false;
f.PaperUnits = 'centimeters';
f.PaperSize = [2.5 2.5];
f.PaperPosition = [0.0 0.0 2.5, 2.5];
f.Color = 'white';
writer = VideoWriter('../lecture/images/lissajous.mp4', 'MPEG-4');
writer.FrameRate = 25;
@ -40,8 +42,10 @@ for i = 1:max_frames
end
f = figure();
set(f, 'PaperUnits', 'centimeter', 'PaperSize', [5, 5], ...
'PaperPosition', [0, 0, 5, 5], 'Color', 'white')
f.PaperUnits = 'centimeters';
f.PaperSize = [2.5 2.5];
f.PaperPosition = [0.0 0.0 2.5, 2.5];
f.Color = 'white';
scatter(x_positions, y_positions, 10, 'r', 'filled');
xlim([-1.05, 1.05])
@ -51,4 +55,4 @@ yticks([-1., 0., 1.])
xlabel('x')
ylabel('y')
saveas(f, '../lecture/images/lissajous.png')
saveas(f, '../lecture/images/lissajous.png')

View File

@ -1,5 +1,5 @@
frequency = 5; % frequency of the sine wave in Hz
time = 0.01:0.01:1.0; % the time axis
time = 0.01:0.01:1.0; % the time axis in seconds
signal = sin(2 * pi * time * frequency);
plot(time, signal);

View File

@ -3,7 +3,7 @@
We may count the ability of adequately presenting scientific data to
the core competences needed to do science. We need to present data in
a meaningful way that supports understanding of the data and the
results.
results without biases.
\begin{figure}[hb!]
\includegraphics[width=0.9\columnwidth]{convincing}
@ -15,13 +15,13 @@ results.
Plotting data in \matlab{} is rather straight forward for simple line
plots. By calling \code[plot()]{plot(x, y)} a simple line plot will be
created. This figure, however is missing any annotations like axis
created. The resulting figure, however is missing any annotations like axis
labeling, a legend, etc.. There are two options to edit the plot: (i)
the graphical user interface (GUI) or the command line. Both ways have
their right to exist associated with respective pros and cons. The UI
way of editing plots is ideal for experimenting the command line
way of editing plots is ideal for experimenting, the command line
approach is best suited for automation and to achieve a consistent
layout across figures and graphs.
layout across figures and graphs in a paper or thesis.
\begin{figure}
\begin{minipage}[t]{0.6\textwidth}
@ -95,31 +95,35 @@ number of datasets.
Creating a simple line-plot is rather easy. Assuming there exists a
variable \varcode{y} in the \codeterm{Workspace} that contains the
measurement data it is enough to call \code[plot()]{plot(y)}. At the
first call of this function a new window will be opened and the data
will be plotted with as a line plot. If you repeatedly call this
function the current plot will be replaced unless the \code[hold]{hold
on} command was issued before. If it was, the current plot is held
and a second line will be added to it. Calling \code[hold]{hold off}
will release the plot and any subsequent plotting will replace the
previous plot.
In our previous call to \varcode{plot} we have provided just a single
first call of this function a new \codeterm{figure} will be opened and
the data will be plotted with as a line plot. If you repeatedly call
this function the current plot will be replaced unless the
\code[hold]{hold on} command was issued before. If it was, the current
plot is held and a second line will be added to it. Calling
\code[hold]{hold off} will release the plot and any subsequent
plotting will replace the previous plot.
In our previous call to \varcode{plot} we provided just a single
variable containing the y-values of the plot. The x-axis will be
scaled from zero to the number of elements in \varcode{y} the x-values
are automatically substituted assuming a constant stepsize of 1. This
automatic scaling is probably not desired and thus, we need to provide
the missing information ourselves. The respective call will expand to
\code[plot()]{plot(x, y)}. In axis will be scaled from the minimum in
\varcode{x} to the maximum of \varcode{x} and by default it will be
plotted as a line plot with a solid blue line of the with 1pt. A
second plot that is added to the figure will be plotted in red using
the same standard settings. The order of the used colors depends on
the \enterm{colormap} settings which can be adjusted to personal taste
or need. Table\,\ref{plotlinestyles} shows some predefined values that
the missing information ourselves. Thus, we need a second variable
that contains the respective \varcode{x} values. The length of
\varcode{x} and \varcode{y} must be the same otherwise the later call
of the \varcode{plot} function will raise an error. The respective
call will expand to \code[plot()]{plot(x, y)}. The x-axis will be now
be scaled from the minimum in \varcode{x} to the maximum of
\varcode{x} and by default it will be plotted as a line plot with a
solid blue line of the linewidth 1pt. A second plot that is added to the
figure will be plotted in red using the same settings. The
order of the used colors depends on the \enterm{colormap} settings
which can be adjusted to personal taste or
need. Table\,\ref{plotlinestyles} shows some predefined values that
can be chosen for the line style, the marker, or the color. For
additional options consult the help.
\begin{table}[tp]
\begin{table}[htp]
\titlecaption{Predefined line styles (left), colors (center) and
marker symbols (right).}{}\label{plotlinestyles}
\begin{tabular}[t]{lc} \hline
@ -173,33 +177,29 @@ chosen.
not distinguish between red and green.
\item Can you distinguish the colors in a b/w respectively gray
scale print?
\item Color figures in publications often cost extra money.
\item Color figures in publications sometimes cost extra money.
\end{itemize}
\end{important}
\subsection{Changing the axis properties}
The first thing a data plot needs are axis labels with a correct
unit. By calling the functions \code[xlabel]{xlabel('Time [ms]')} and
\code[ylabel]{ylabel{'Voltage [mV]'}} these can be set. By default the
axes will be scaled to show the whole data range. The extremes will be
selected as the closest integer for small values or the next full
multiple of tens, hundreds, thousands, etc.\ depending on the maximum
value. If these defaults do not match our needs, the limits of the
axes can be explicitly set with the functions \code[xlim()]{xlim()}
and \code[ylim()]{ylim()}. To do this, the functions expect a single
argument, that is a vector containing the minimum and maximum
value. Table\,\ref{plotaxisprops} lists some of the commonly adjusted
properties of an axis. These properties can be set using the
\code[set()]{set()} function. The \code{set} function expects as a
first argument a \enterm{handle} of the affected axis. An axis handle
of the current plot is returned by the \code[gca]{gca} function (gca
stands for ``get current axis''). The following arguments passed to
\code{set} are pairs of the property name and the desired value. It is
possible to set any number of properties using a single call to
\code{set}. See listing\,\ref{niceplotlisting} (lines 20 and 21) for
an example (these commands could be joined into a single call to
\code{set} but have been split for better readability).
\subsection{Changing the axes properties}
The first thing a plot needs are axis labels with correct units. By
calling the functions \code[xlabel]{xlabel('Time [ms]')} and
\code[ylabel]{ylabel('Voltage [mV]')} these can be set. By default the
axes will be scaled to show the full extent of the data. The extremes
will be selected as the closest integer for small values or the next
full multiple of tens, hundreds, thousands, etc.\ depending on the
maximum value. If these defaults do not match your needs, the limits
of the axes can be explicitly set with the functions
\code[xlim()]{xlim()} and \code[ylim()]{ylim()}. To do this, the
functions expect a single argument, that is a 2-element vector
containing the minimum and maximum value. Table\,\ref{plotaxisprops}
lists some of the commonly adjusted properties of an axis. To set
these properties, we need to have the axes object which can either be
stored in a variable when calling \varcode{plot} (\code{axes =
plot(x,y);}) or can be retrieved using the \code[gca]{gca} function
(gca stands for ``get current axes''). Changing the properties of the axes
object will update the plot (listing\,\ref{niceplotlisting}).
\begin{table}[tp]
\titlecaption{Incomplete list of axis properties.}{For a complete
@ -247,27 +247,30 @@ an example (these commands could be joined into a single call to
\end{tabular*}
\end{table}
Like axes, also figure has several properties that can be adjusted to
the current needs. Most notably the paper (figure) size and the
placement of the axes on the paper. Table\,\ref{plotfigureprops} lists
commonly used properties. For a complete reference check the help. To
change the properties, we again use the \code{set()} function. The
first argument is now a handle to the current figure, not the current
axis as before. Analogously to the \code{gca} command there is a
\code{gcf} (``get current figure'') command with which the handle can
be retrieved.
Like the axes, also the figure has several properties that can be
adjusted to the current needs. Most notably the paper (figure) size
and the placement of the axes on the
paper. Table\,\ref{plotfigureprops} lists commonly used
properties. For a complete reference check the help. To change the
figure's appearance, we need to change the properties of the figure
object which can be retrieved during creation of the figure (\code{fig
= figure();}) or by using the \code{gcf} (``get current figure'')
command.
The script shown in the listing\,\ref{niceplotlisting} exemplifies
several features of the plotting system and automatically generates
and saves figure\,\ref{spikedetectionfig}. With any execution of this
script exactly the same plot will be created. If we decided to plot a
different recording, the format will stay exactly the same, just the
data changes. Of special interest are the lines 22 and 23 which set
the size of the figure and positions the axes on the paper. Line 26
finally saves the figure in the 'pdf' format to file. When calling the
function \code{saveas()} the first argument is the current figure
handle, the second the file name, and the last one defines the
output format (box\,\ref{graphicsformatbox}).
data changes. Of special interest are the lines 35 through 37 which
set the size of the figure and positions the axes on the paper. Lines
24 through 27 control the font used for labeling inside the axes. The
axes holds the default \varcode{FontSize} and via multipliers applied
to the default one can control the size of the title (line 26) or the
axes labels (line 27). Line 40 finally saves the figure in the 'pdf'
format to file. When calling the function \code{saveas()} the first
argument is the current figure handle, the second the file name, and
the last one defines the output format (box\,\ref{graphicsformatbox}).
\begin{figure}[t]
\includegraphics{spike_detection} \titlecaption{Automatically
@ -325,6 +328,37 @@ output format (box\,\ref{graphicsformatbox}).
label=niceplotlisting]{automatic_plot.m}
\begin{ibox}[t]{\label{handlevsobjectbox}The wind of change.}
The way figure or axis properties can be adapted has been changed
with recent \matlab{} versions. In versions before \emph{R2014b}
properties could be read and set using the functions
\code[get()]{get} and \code[set()]{set}. The first argument these
functions expect are valid figure or axis \emph{handles} which were
returned by the \code{figure} and \code{plot} functions, or could be
retrieved using \code[gcf()]{gcf} or \code[gca()]{gca} for the
current figure or axis handle, respectively. Subsequent arguments
passed to \code{set} are pairs of a property's name and the desired
value.
\begin{lstlisting}[caption={Using set to change figure and axis properties.}]
frequency = 5; % frequency of the sine wave in Hz
time = 0.01:0.01:1.0; % the time axis in seconds
signal = sin(2 * pi * time * frequency);
plot(time, signal)
axes_handle = gca(); % get current axes
figure_handle = gcf(); % get current figure
set(axes_handle, 'XLabel', 'time [s]', 'YLabel', 'amplitude');
set(figure_handle, 'PaperSize', [5.5, 5.5], 'PaperUnit', 'centimeters', ...
'PaperPosition', [0, 0, 5.5, 5.5]);
\end{lstlisting}
With newer versions the handles returned by \varcode{gcf} and
\varcode{gca} are ``objects'' and setting properties became much
easier as it is used throughout this chapter. For downward
compatibility with older versions set and get still work in current
versions of \matlab{}.
\end{ibox}
\section{Plot examples}
So far we have introduced the standard line plots. Next to these there
@ -485,7 +519,7 @@ its properties. See the \matlab{} help for more information.
\lstinputlisting[caption={Illustrating estimation errors using error bars. Script that
creates \figref{errorbarplot}. A, B},
label=errorbarlisting, firstline=13, lastline=29,
label=errorbarlisting, firstline=13, lastline=31,
basicstyle=\ttfamily\scriptsize]{errorbarplot.m}
\subsubsection{Fill}
@ -507,7 +541,7 @@ version of the x-values to the original x-values using \code{cat} and
\code{fliplr} for concatenation and inversion, respectively (line 3 in
listing \ref{errorbarlisting2}; Depending on the layout of your data
you may need concatenate along a different dimension of the data and
use \code{flipud} instead). The y-coordinates of the polygon vertices
use \code{flipud} instead). The y-coordinates of the polygon vertices
are concatenated in a similar way (line 4). In the example shown here
we accept the polygon object that is returned by fill (variable p) and
use it to change a few properties of the polygon. The \emph{FaceAlpha}
@ -519,7 +553,7 @@ connecting the average values (line 12).
\lstinputlisting[caption={Illustrating estimation errors using a shaded area. Script that
creates \figref{errorbarplot} C.}, label=errorbarlisting2,
firstline=30,
firstline=33,
basicstyle=\ttfamily\scriptsize]{errorbarplot.m}
\subsection{Annotations, text}
@ -600,7 +634,7 @@ Lissajous figure. The basic steps are:
\end{enumerate}
\lstinputlisting[caption={Making animations and saving them as a
movie.}, label=animationlisting, firstline=3, lastline=33,
movie.}, label=animationlisting, firstline=16, lastline=36,
basicstyle=\ttfamily\scriptsize]{movie_example.m}
\section{What makes a good plot?}