Datenvisualisierung mit

Matplotlib

Als erstes: IPython interaktiv machen:

In [1]:
%matplotlib inline
# bei euch: %matplotlib (nur in iPython)

Um mit Matplotlib arbeiten zu können, muss die Bibliothek erst einmal importiert werden. Damit wir nicht so viel tippen müssen geben wir ihr einen kürzeren Namen:

In [2]:
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (10, 8)
plt.rcParams['font.size'] = 16
plt.rcParams['lines.linewidth'] = 2

Außerdem brauchen wir ein paar Funktion aus numpy, die euch schon bekannt sind

In [3]:
import numpy as np

Ein einfaches Beispiel: $f(x)=x^2$

In [4]:
x = np.linspace(0, 1) # gibt 50 Zahlen in gleichmäßigem Abstand von 0–1
plt.plot(x, x**2)
# Falls nicht interaktiv: 
# plt.show()
Out[4]:
[<matplotlib.lines.Line2D at 0x7fbcf3a6cef0>]

Anderes Beispiel: $\sin(t)$ mit verschiedenen Stilen. Vorsicht, die Funktionen und $\pi$ sind Bestandteil von numpy

In [5]:
t = np.linspace(0, 2 * np.pi)
plt.plot(t, np.sin(t))
Out[5]:
[<matplotlib.lines.Line2D at 0x7fbcf3a41f28>]
In [6]:
plt.plot(t, np.sin(t), 'r--')
Out[6]:
[<matplotlib.lines.Line2D at 0x7fbcf39b07f0>]
In [7]:
plt.plot(t, np.sin(t), 'go')
Out[7]:
[<matplotlib.lines.Line2D at 0x7fbcf3994a20>]

Tabelle mit allen Farben und Styles: matplotlib.axes.Axes.plot

Neue Grenzen mit xlim(a, b) und ylim(a, b)

In [8]:
plt.plot(t, np.sin(t))
plt.xlim(0, 2 * np.pi)
plt.ylim(-1.2, 1.2)
Out[8]:
(-1.2, 1.2)

Es fehlt noch etwas...

XKCD comic on why you should label your axes.

In [9]:
with plt.xkcd():
    plt.title('Axes with labels')
    plt.plot(t, np.sin(t))
    plt.xlabel('t / s')
    plt.ylabel('U / V')
    plt.ylim(-1.1, 1.1)
    plt.xlim(0, 2 * np.pi)

Achsen-Beschriftungen können mit LaTeX-Code erstellt werden → LaTeX-Kurs in der nächsten Woche.

In [10]:
plt.plot(t, np.sin(t))
plt.xlabel(r'$t / \mathrm{s}$')
plt.ylabel(r'$U / \mathrm{V}$')
Out[10]:
Text(0,0.5,'$U / \\mathrm{V}$')

Einheiten in Achsenbeschriftungen werden wegdividiert:

In [11]:
plt.plot(t, np.sin(t))
plt.xlabel(r'$t / \mathrm{s}$')
plt.ylabel(r'$U \,/\, \mathrm{V}$')  # Spaces sind Geschmacksfrage……
Out[11]:
Text(0,0.5,'$U \\,/\\, \\mathrm{V}$')

Mehr zu Einheiten gibt es im LaTeX-Kurs.

Legende

Legenden für Objekte die ein label tragen

In [12]:
plt.plot(t, np.sin(t), label=r'$\sin(t)$')
plt.legend()
#plt.legend(loc='lower left')
#plt.legend(loc='best')
Out[12]:
<matplotlib.legend.Legend at 0x7fbcf3693940>

Seit matplotlib 2.0.2 ist loc=best standardmäßig eingestellt.

Andere möglche Orte für die Legende findest du hier:

https://matplotlib.org/api/legend_api.html

Gitter

Mit grid() wird ein Gitter erstellt:

In [13]:
plt.plot(t, np.sin(t))
plt.grid()

Laden von Daten

In [14]:
x, y = np.genfromtxt('example_data.txt', unpack=True)
plt.plot(x, y, 'k.')

t = np.linspace(0, 10)
plt.plot(t, 5 * t, 'r-')
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-14-739ca79bc1fd> in <module>()
----> 1 x, y = np.genfromtxt('example_data.txt', unpack=True)
      2 plt.plot(x, y, 'k.')
      3 
      4 t = np.linspace(0, 10)
      5 plt.plot(t, 5 * t, 'r-')

~/.local/anaconda3/lib/python3.6/site-packages/numpy/lib/npyio.py in genfromtxt(fname, dtype, comments, delimiter, skip_header, skip_footer, converters, missing_values, filling_values, usecols, names, excludelist, deletechars, replace_space, autostrip, case_sensitive, defaultfmt, unpack, usemask, loose, invalid_raise, max_rows, encoding)
   1687             fname = str(fname)
   1688         if isinstance(fname, basestring):
-> 1689             fhd = iter(np.lib._datasource.open(fname, 'rt', encoding=encoding))
   1690             own_fhd = True
   1691         else:

~/.local/anaconda3/lib/python3.6/site-packages/numpy/lib/_datasource.py in open(path, mode, destpath, encoding, newline)
    258 
    259     ds = DataSource(destpath)
--> 260     return ds.open(path, mode, encoding=encoding, newline=newline)
    261 
    262 

~/.local/anaconda3/lib/python3.6/site-packages/numpy/lib/_datasource.py in open(self, path, mode, encoding, newline)
    614                                       encoding=encoding, newline=newline)
    615         else:
--> 616             raise IOError("%s not found." % path)
    617 
    618 

OSError: example_data.txt not found.

Auslagern in ein Skript

Speichert den folgenden Code in eine Textdatei plot.py ab.

Öffnet ein Terminal und startet das Programm:

python plot.py
In [15]:
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 1)
plt.plot(x, x**2, 'b-')
plt.savefig('plot.pdf')

Mit savefig speichert man die Abbildung.

In diesem Fall sollte die Datei plot.pdf erstellt worden sein.

Es gibt viele Ausgabeformate: pdf, png, svg, LaTeX

Um mehrere Plots zu speichern kann man plt.clf() verwenden. Der Befehl leert die aktuelle figure und steht für clear figure.

In [16]:
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 1)

### Plot 1
plt.clf()


plt.plot(x, x**2, 'b-',label='Plot 1')
plt.legend()
plt.savefig('plot_1.pdf')

### Plot 2
plt.clf()

plt.plot(x, x**3, 'r-')
plt.savefig('plot_2.pdf')

Komplexere Abbildungen

Natürlich kann man mehrere Linien in einen Plot packen:

In [17]:
x = np.linspace(0, 1)

plt.plot(x, x**2, label=r'$x^2$')
plt.plot(x, x**4)
plt.plot(x, x**6, 'o', label=r'$x^6$')

plt.legend()
Out[17]:
<matplotlib.legend.Legend at 0x7fbcf3585320>

Es werden nur die Plots in der Legende angezeigt, die ein Label haben.

Man kann auch mehrere Plots in ein Bild packen:

In [18]:
x = np.linspace(0, 2 * np.pi)

# #rows, #columns, plot index = row * (#cols) + col
plt.subplot(2, 1, 1)
plt.plot(x, x**2)
plt.xlim(0, 2 * np.pi)

plt.subplot(2, 1, 2)
plt.plot(x, np.sin(x))
plt.xlim(0, 2 * np.pi)
Out[18]:
(0, 6.283185307179586)