RWTH Plots with Matplotlib

rwth_nb.plots.mpl_decorations extends Matplotlib to some useful functionality explained below

  1. Simple Plots

    1. Graph Plot

    2. Stem Plot

    3. Multiple Plots

    4. Updating Plots

  2. Annotations

    1. Ticks

    2. Distances

  3. Misc

    1. Signal processing

      1. Dirac Impulses

      2. Pole-Zero Diagrams


Simple Plots

Graph Plot

See also: * Matplotlib pyplot tutorial * Axis Styles

[1]:
import matplotlib.pyplot as plt
import numpy as np
import rwth_nb.plots.mpl_decorations as rwth_plt

# numpy array
x = np.linspace(-5,5)

# create figure
fig, ax = plt.subplots()

# call axis and grid for beautification
rwth_plt.axis(ax);
rwth_plt.grid(ax)

# plot to axis while color is in RWTH Colors
ax.plot(x, x**2, 'rwth:blue');

# set x- and y-labels
ax.set_xlabel(r'$\rightarrow x$');
ax.set_ylabel(r'$\uparrow f(x)=x^2$');
/usr/local/lib/python3.8/site-packages/traitlets/traitlets.py:3030: FutureWarning: --rc={'figure.dpi': 96} for dict-traits is deprecated in traitlets 5.0. You can pass --rc <key=value> ... multiple times to add items to a dict.
  warn(
[1]:
Text(0.0, 1, '$\\uparrow f(x)=x^2$')
../_images/examples_RWTH_Plots_2_2.svg

where * rwth_plt.axis(ax) relocates the axes spines, * rwth_plt.grid(ax) displays an additional grid.

Axis Styles

Relocate axes spines.

rwth_plt.axis(ax)

Grid

Displays grid.

rwth_plt.grid(ax)

Stem Plot

See also:

[2]:
import matplotlib.pyplot as plt
import numpy as np
import rwth_nb.plots.mpl_decorations as rwth_plt

n = np.linspace(-5, 5, 11)

fig, ax = plt.subplots()
rwth_plt.axis(ax); rwth_plt.grid(ax)
ax.set_xlabel(r'$\rightarrow n$');
ax.set_ylabel(r'$\uparrow f(n)=n$');

# stem plot
rwth_plt.stem(ax, n, n, 'rwth:blue');
[2]:
<StemContainer object of 3 artists>
../_images/examples_RWTH_Plots_8_1.svg

Multiple Plots

Plots can be combined by using matplotlib.pyplot.subplots(), where arguments are unpacked from rwth_plt.landscape for 16/9 landscape view. Optionally, own figure sizes can be defined.

See also: Matplotlib subplots

[3]:
import matplotlib.pyplot as plt
import numpy as np
import rwth_nb.plots.mpl_decorations as rwth_plt

t = np.linspace(-5, 5, 10001)

fig, axs = plt.subplots(1, 2, **rwth_plt.landscape)

ax = axs[0]
rwth_plt.axis(ax); rwth_plt.grid(ax)
ax.plot(t, t**2, 'rwth:blue')

ax = axs[1]
rwth_plt.axis(ax); rwth_plt.grid(ax)
ax.plot(t, t**3, 'rwth:red');
[3]:
[<matplotlib.lines.Line2D at 0x7f89af3cfbe0>]
../_images/examples_RWTH_Plots_11_1.svg

Updating Plots

Plots can be dynamically updated for more efficient usage.
This is essential when using Widgets.

Graphs

[4]:
import matplotlib.pyplot as plt
import numpy as np
import rwth_nb.plots.mpl_decorations as rwth_plt

from ipywidgets import widgets

# initial plot
# create figure
fig, ax = plt.subplots()

# call axis and grid for beautification
rwth_plt.axis(ax);
rwth_plt.grid(ax)

# plot to axis
# this time: save plotted lines to a variable
x = np.linspace(-5, 5, 10001)
n = 1

line, = ax.plot(x, x**n, 'rwth:blue');

# set x- and y-labels
ax.set_xlabel(r'$\rightarrow x$');
ax.set_ylabel(r'$\uparrow f(x)=x^{}$'.format(n));

# set up widget for updating n (see RWTH Widgets.ipynb)
@widgets.interact(n=widgets.IntSlider(min=1, max=6, step=1, description='$n$', style=rwth_plt.wdgtl_style))
def update_n(n):
    # updating plot
    # change lines' y-data
    line.set_ydata(x**n)

    # change label
    ax.set_ylabel(r'$\uparrow f(x)=x^{}$'.format(n));
../_images/examples_RWTH_Plots_14_0.svg

Stems

Stem plots are stored in so called containers. These can be manipulated efficiently using

stem_set_data(container, x, y)
stem_set_xdata(container, x)
stem_set_ydata(container, y)
[5]:
import matplotlib.pyplot as plt
import numpy as np
import rwth_nb.plots.mpl_decorations as rwth_plt

from ipywidgets import widgets

a = .5
n = np.linspace(-5, 5, 11)

fig, ax = plt.subplots()
rwth_plt.axis(ax); rwth_plt.grid(ax)

ax.set_xlabel(r'$\rightarrow n$');
ax.set_ylabel(r'$\uparrow f(n)={}\cdot n$'.format(a));

# initial stem plot
stem_container = rwth_plt.stem(ax, n, n, 'rwth:blue');

# set up widget for updating n (see RWTH Widgets.ipynb)
@widgets.interact(a=widgets.FloatSlider(min=-1, max=1, step=.1, value=.5, description='$a$', style=rwth_plt.wdgtl_style))
def update_a(a):

    # change stem data
    rwth_plt.stem_set_ydata(stem_container, a*n)

    # change label
    ax.set_ylabel(r'$\uparrow f(x)={}\cdot n$'.format(a));
../_images/examples_RWTH_Plots_16_0.svg

Annotations

Ticks

annotate_xtick

[6]:
%matplotlib inline

x0 = 2

fig,ax = plt.subplots(); ax.plot(x, (x-x0)**2, 'rwth:blue');
ax.set_xlabel(r'$\rightarrow x$'); ax.set_ylabel(r'$\uparrow f(x)=(x-x_0)^2$')
rwth_plt.axis(ax); rwth_plt.grid(ax);

rwth_plt.annotate_xtick(ax, r'$x_0$', x0, x0**2 );
[6]:
(Text(2, 4, '$x_0$'), <matplotlib.lines.Line2D at 0x7f89af42d550>)
../_images/examples_RWTH_Plots_20_1.svg

annotate_ytick

[7]:
x0 = 2

fig,ax = plt.subplots(); ax.plot(x, (x-x0)**2, 'rwth:blue');
ax.set_xlabel(r'$\rightarrow x$'); ax.set_ylabel(r'$\uparrow f(x)=(x-x_0)^2$')
rwth_plt.axis(ax); rwth_plt.grid(ax);

rwth_plt.annotate_ytick(ax, r'$y_0$', -1, 4 );
[7]:
(Text(-1, 4, '$y_0$'), <matplotlib.lines.Line2D at 0x7f89af1bb910>)
../_images/examples_RWTH_Plots_22_1.svg

Distances

annotate_distance

[8]:
Delta = 3

fig,ax = plt.subplots(); ax.plot(x, np.exp(-(x/np.sqrt(Delta))**2), 'rwth:blue');
ax.set_xlabel(r'$\rightarrow x$');
rwth_plt.axis(ax); rwth_plt.grid(ax);

rwth_plt.annotate_distance(ax, r'$\Delta$', [-Delta/2,.5], [Delta/2,.5]);
[8]:
(Text(1.5, 0.5, ''), Text(0, -2, '$\\Delta$'))
../_images/examples_RWTH_Plots_24_1.svg

Misc

Signal processing

Dirac impulses

plot_dirac, dirac_weights

[9]:
# set up plot
fig,ax = plt.subplots(1,1);
ax.set_xlim([-2.75, 2.75]); ax.set_ylim([0, 2.4]); rwth_plt.grid(ax); rwth_plt.axis(ax);

# dirac x positions
dirac_x = [-1, 0, 1]

# dirac weights
dirac_weights = [1, 2, 1]

# plot diracs
rwth_plt.plot_dirac(ax, dirac_x, dirac_weights, 'rwth:blue');

# show weights
rwth_plt.dirac_weights(ax, dirac_x, dirac_weights, dirac_weights, color='rwth:black')
../_images/examples_RWTH_Plots_28_0.svg

Pole-Zero Diagrams

plot_lroc Laplace Domain

[10]:
# poles (pp) and zeros (pz)
pp = np.array([-1, 1+1j]); pz = np.array([0, 3-2j])

# poles' and zeros' orders
ord_p = np.array([1, 2]); ord_z = np.array([1, 1])

# region of convergence
roc = np.array([np.max(np.real(pp)), np.inf])

# set up plot
fig, ax = plt.subplots()
ax.set_xlabel(r'$\rightarrow \mathrm{Re}$'); ax.set_ylabel(r'$\uparrow \mathrm{Im}$');
ax.set_xlim(-2.5, 3.5); ax.set_ylim(-5, 5); rwth_plt.grid(ax); rwth_plt.axis(ax); ax.set_title('Pole-Zero Diagram');

# plot poles and zeros
ax.plot(np.real(pp), np.imag(pp), **rwth_plt.style_poles); ax.plot(np.real(pp), -np.imag(pp), **rwth_plt.style_poles);
ax.plot(np.real(pz), np.imag(pz), **rwth_plt.style_zeros); ax.plot(np.real(pz), -np.imag(pz), **rwth_plt.style_zeros);

# show poles' and zeros' orders
rwth_plt.annotate_order(ax, pp, ord_p)
rwth_plt.annotate_order(ax, pz, ord_z)

# show S_0
S_0 = 1
ax.text(2, 4, r'$S_0 =$ ' + str(S_0), fontsize=12, bbox=rwth_plt.wbbox)

# plot region of convergence
rwth_plt.plot_lroc(ax, roc);
[10]:
[<matplotlib.lines.Line2D at 0x7f89aefeb760>,
 <matplotlib.lines.Line2D at 0x7f89aefebac0>,
 <matplotlib.collections.PolyCollection at 0x7f89aefebdf0>]
../_images/examples_RWTH_Plots_30_1.svg

plot_zroc \(z\)-Domain

[11]:
# poles (zp) and zeros (zz)
zp = np.array([0.5, 1+1j]); zz = np.array([0])

# poles' and zeros' orders
ord_p = np.array([1, 2]); ord_z = np.array([1])

# region of convergence
roc = np.array([0.5, 1+1j])

# set up plot
fig, ax = plt.subplots()
ax.set_xlabel(r'$\rightarrow \mathrm{Re}$'); ax.set_ylabel(r'$\uparrow \mathrm{Im}$');
rwth_plt.grid(ax); rwth_plt.axis(ax); ax.set_title('Pole-Zero Diagram');

# square plot (!)
ax.set_aspect('equal')

# plot poles and zeros
ax.plot(np.real(zp), np.imag(zp), **rwth_plt.style_poles); ax.plot(np.real(zp), -np.imag(zp), **rwth_plt.style_poles);
ax.plot(np.real(zz), np.imag(zz), **rwth_plt.style_zeros); ax.plot(np.real(zz), -np.imag(zz), **rwth_plt.style_zeros);

# show orders
rwth_plt.annotate_order(ax, zp, ord_p)
rwth_plt.annotate_order(ax, zz, ord_z)

# plot region of convergence
rwth_plt.plot_zroc(ax, roc);
[11]:
<matplotlib.patches.Polygon at 0x7f89aeeed0a0>
../_images/examples_RWTH_Plots_32_1.svg

This code is licensed under the MIT license.