Matplotlib Tutorial: Spines und Ticks


Verschieben der Grenzlinien und Polierung der Achsenbezeichnungen

spines

Der Begriff "spine" wohl meistens bekannt in Bezug auf das RÌckgrat oder die WirbelsÀule des menschlichen Skeletts. Eine weitere Bedeutung steht fÌr eine "Buch-HÌlle". Unser Bild auf der rechten Seite zeigt die Stacheln eines Kaktus, kÌnstlerisch verÀndert, damit es aussieht wie ein Brustkorb. Sie werden in einer Bibliothek kaum etwas finden zur Anwendung von Matplotlib. Stacheln in Matplotlib bezeichnen die Linien, welche die Achsen-Markierungen verbinden unter BerÌcksichtigung des Datenbereichs.

Wir demonstrieren im Folgenden, dass die Stacheln (spines) an beliebigen Stellen gesetzt werden können.

Bevor wir damit beginnen können, fÌhren wir die gca-Funktion ein. Diese liefert zu aktuellen Instanzen der Achsen der aktuellen Figur zurÌck.

Wir können zum Beispiel plt.gca(projection='polar') aufrufen um die aktuellen Polar-Achsen zu erhalten.

In [1]:
# the next "inline" statement is only needed,
# if you are working with "ipython notebook"
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

X  = np.linspace(-2 * np.pi, 2 * np.pi, 70, endpoint=True)
F1 = np.sin(2* X)
F2 = (2*X**5 + 4*X**4 - 4.8*X**3 + 1.2*X**2 + X + 1)*np.exp(-X**2)

# get the current axes, creating them if necessary:
ax = plt.gca()

# making the top and right spine invisible:
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

# moving bottom spine up to y=0 position:
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))

# moving left spine to the right to position x == 0:
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

plt.plot(X, F1)
plt.plot(X, F2)

plt.show()


Ticks anpassen

Matplotlib hat bis jetzt - in allen vorangegangenen Beispielen - automatisch den Abstand der Punkte auf der Achse ermittelt. In unserem vorigen Beispiel haben wir gesehen dass die X-Achse mit -8, -6. -4, -2, 0, 2, 4, 6, 8 nummeriert war, wÀhrend die Y-Achse mit -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0 beschriftet ist.

xticks ist eine Methode, die fÌr das Abfragen und VerÀndern von Tick-Positionen und Beschriftungen benutzt werden kann. Das gleiche gilt fÌr die Methode yticks.

In [2]:
# get the current axes, creating them if necessary:
ax = plt.gca()

locs, labels = plt.xticks()
print(locs, labels)

locs, labels = plt.yticks()
print(locs, labels)
[ 0.   0.2  0.4  0.6  0.8  1. ] <a list of 6 Text xticklabel objects>
[ 0.   0.2  0.4  0.6  0.8  1. ] <a list of 6 Text yticklabel objects>

Wie bereits erwÀhnt, kann xticks ebenso dazu verwendet werden, um die Position der Ticks auf der X-Achse zu verÀndern:

In [4]:
plt.xticks( np.arange(10) )

locs, labels = plt.xticks()
print(locs, labels)
[0 1 2 3 4 5 6 7 8 9] <a list of 10 Text xticklabel objects>

Jetzt verÀndern wir sowohl die Position als auch die Beschriftung der Ticks auf der X-Achse:

In [5]:
# set the locations and labels of the xticks
plt.xticks( np.arange(4), 
           ('Berlin', 'London', 'Hamburg', 'Toronto') )
Out[5]:
([<matplotlib.axis.XTick at 0x10ccbfef0>,
  <matplotlib.axis.XTick at 0x10ca7e320>,
  <matplotlib.axis.XTick at 0x10bead588>,
  <matplotlib.axis.XTick at 0x10cedff98>],
 <a list of 4 Text xticklabel objects>)

Gehen wir nochmal zurÃŒck zum vorigen Beispiel der Trigonometrischen Funktionen. Die meisten werden Faktoren von Pi fÃŒr die X-Achse fÃŒr geeigneter halten als die einfachen Integer-Werte:

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

X = np.linspace(-2 * np.pi, 2 * np.pi, 70, endpoint=True)
X = np.linspace(-2 * np.pi, 2 * np.pi, 70, endpoint=True)
F1 = np.sin(X**2)
F2 = X * np.sin(X)

# get the current axes, creating them if necessary:
ax = plt.gca()

# making the top and right spine invisible:
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

# moving bottom spine up to y=0 position:
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))

# moving left spine to the right to position x == 0:
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

plt.xticks( [-6.28, -3.14, 3.14, 6.28])
plt.yticks([-3, -1, 0, +1, 3])
plt.plot(X, F1)
plt.plot(X, F2)

plt.show()


VerÀndern der Tick-Beschriftungen

Wir möchten nun die Beschriftungen der Ticks auf der X-Achse umbenennen und durch eigene Markierungen ersetzen. Wir benutzen dafÃŒr ebenfalls die Methode xticks wie auch schon im vorigen Beispiel. Diesesmal jedoch, rufen wir xticks mit zwei Parametern auf: Der erste ist die gleiche Liste die wir auch schon vorher benutzt haben, d.h. Positionen auf der X-Achse, an denen die Ticks gesetzt werden sollen. Der zweite Parameter ist eine Liste der gleichen Größe mit den entsprechenden LaTeX Tick-Markierungen, d.h. der Text der anstelle der Werte sehen möchten. Die LaTeX-Schreibweise muss ein raw-String sein um den Escape-Mechanismus von Python abzustellen, da in LaTeX das Backslash sehr stark genutzt wird.

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

X = np.linspace(-2 * np.pi, 2 * np.pi, 70, endpoint=True)

F1 = X * np.sin(X)

ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

# labelling the X ticks:
plt.xticks( [-6.28, -3.14, 3.14, 6.28],
        [r'$-2\pi$', r'$-\pi$', r'$+\pi$', r'$+2\pi$'])
plt.yticks([-3, -1, 0, +1, 3])


plt.plot(X, F1)

plt.show()


Justierung der Tick-Beschriftungen

Wir wollen die Lesbarkeit der Tick-Beschriftungen erhöhen. Dazu vergrößern wir die Schrift und zeichnen dies auf einen halbtransparenten Hintergrund.

In [27]:
print(ax.get_xticklabels())
<a list of 4 Text xticklabel objects>

In [28]:
for xtick in ax.get_xticklabels():
    print(xtick)
Text(-6.28,0,'$-2\\pi$')
Text(-3.14,0,'$-\\pi$')
Text(3.14,0,'$+\\pi$')
Text(6.28,0,'$+2\\pi$')

In [29]:
labels = [xtick.get_text() for xtick in ax.get_xticklabels()]
print(labels)
['$-2\\pi$', '$-\\pi$', '$+\\pi$', '$+2\\pi$']

Jetzt vergrößern wir die Schrift und stellen die Transparenz ein:

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

X = np.linspace(-2 * np.pi, 2 * np.pi, 170, endpoint=True)
F1 = np.sin(X**3 / 2)

ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

plt.xticks( [-6.28, -3.14, 3.14, 6.28],
        [r'$-2\pi$', r'$-\pi$', r'$+\pi$', r'$+2\pi$'])
plt.yticks([-3, -1, 0, +1, 3])


for xtick in ax.get_xticklabels():
    xtick.set_fontsize(18)
    xtick.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.7 ))

for ytick in ax.get_yticklabels():
    ytick.set_fontsize(14)
    ytick.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.7 ))
    
plt.plot(X, F1, label="$sin(x)$")

plt.legend(loc='lower left')

plt.show()