RWTH Plots with Matplotlib¶
rwth_nb.plots.mpl_decorations
extends Matplotlib to some useful functionality explained below
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$')
where * rwth_plt.axis(ax)
relocates the axes spines, * rwth_plt.grid(ax)
displays an additional grid.
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>
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>]
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));
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));
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>)
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>)
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$'))
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')
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>]
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>
This code is licensed under the MIT license.