Γλώσσα Προγραμματισμού ΙΙ

Διάλεξη 31ης Μαρτίου 2015 - Η βιβλιοθήκη matplotlib

Η matplotlib είναι μια βιβλιοθήκη γραφικών της Python η οποία μπορεί να παράξει ένα μεγάλο είδος από γραφικές παραστάσεις, είτε μέσω προγραμμάτων Python, είτε κατευθείαν από ένα διαδραστικό περιβάλλον, π.χ. το ipython shell. Ο ενδιαφερόμενος αναγνώστης μπορεί να δεί στην ιστοσελίδα http://matplotlib.org/examples/index.html ένα πλήθος από προγράμματα (scripts) που παράγουν γραφικές παραστάσεις, καθώς και μια έκθεση γραφικών παραστάσεων. Το επίσημο εγχειρίδιο χρήσης βρίσκεται στην ιστοσελίδα http://matplotlib.org/users/intro.html από την οποία δανειζόμαστε τις πληροφορίες που παρουσιάζουμε παρακάτω.

Ένα πρώτο παράδειγμα γραφικής παράστασης με την matplotlib φαίνεται παρακάτω μαζί με τις εντολές που χρειαάστηκαν γι' αυτό. Στο συγκεκριμένο παράδειγμα, ενώνουμε με μια μπλέ τεθλασμένη γραμμή τις συντεταγμένες των σημείων $(1,1), (2,4), (3,9), (4,16)$.


import matplotlib.pyplot as plt
plt.plot([1,2,3,4], [1,4,9,16])
plt.axis([0, 6, 0, 20])
plt.show()

Παρατηρούμε κατ΄ αρχήν ότι στην εντολή plot() δίνουμε ως μοναδικά ορίσματα δύο λίστες με τις $x$-, αντίστοιχα, $y$-συντεταγμένες των σημείων που μας ενδιαφέρουν. Η προκαθορισμένη συμπεριφορά της συνάρτησης plot() είναι να ενώσει αυτά τα σημεία με μια μπλέ, συνεχόμενη γραμμή. Η εντολή axis() ορίζει τις κλίμακες στους δύο άξονες: το διάστημα $[0,6]$ στον ορίζόντιο άξονα και $[0,20]$ στον κάθετο άξονα. Τέλος, η εντολή show() εμφανίζουν στην οθόνη το γράφημα. Είναι εύκολο να αλλάξουμε τα χαρακτηριστικά του γραφήματος προσθέτοντας επιπλέον ορίσματα στην εντολή plot(). Για παράδειγμα, προσθέτοντας το όρισμα 'ro' θα δούμε τις συντεταγμένες των σημείων σημειωμένες με κόκκινους (r, red) κύκλους (o) αλλά όχι την μπλέ γραμμή.

Στον κώδικα που ακολουθεί σχεδιάζουμε παραπάνω από μια γραφικές παραστάσεις χρησιμοποιώντας μόνο μια φορά την εντολή plot και πολλά διαφορετικά στύλ γραμμών:


import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0., 5., 0.2)
# red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()

Στο σχήμα δεξιά έχουμε ζωγραφίσει τα σημεία την $y = x$ με διακεκομμένη κόκκινη γραμμή, τα σημεία $(0,0), (0.2, 0.4), \ldots, (5, 25)$ με μπλέ τετραγωνάκια, και τα αντίστοιχα σημεία στην γραφική παράσταση της $y = x^3$ με πράσινα τρίγωνα. Όπως φαίνεται από το παραπάνω μπορούνε να προσδιορίσουμε το χρώμα της γραμμής με ένα από τους χαρακτήρες ('b', blue, 'g', green, 'r', red', 'c', cyan, 'm', magenta, 'y' yellow, 'k', black, 'w', white) και το είδος της γραμμής με τους χαρακτήρες '-',  '--',  '-.',  και ':'. Μπορούμε ακόμα να αλλάξουμε το πάχος της γραμμής με την οποία σχεδιάζεται μια γραφική παράσταση με την οδηγία linewidth. Για παράδειγμα μπορούμε να σχεδιάσουμε τη γραφική παράσταση της $y = sin(x)$ στο διάστημα $[0,2\pi]$ και με το διπλάσιο πάχος γραμμής από το συνηθισμένο με την εντολή plt.plot(x, y, linewidth=2.0). Εδώ έχουμε θέσει x = linspace(0, 2*np.pi, 100) και y = np.sin(x).

Είναι επίσης εύκολο να σχεδιάσουμε στο ίδιο παράθυρο γραφικών περισσότερες από μια γραφικές παραστάσεις με την εντολή subplot(). Στο παράδειγμα που ακολουθεί σχεδιάζουμε την γραφική παράσταση της συνάρτσης $e^{-x}\cos(2\pi x)$ και της $coѕ(2\pi x)$, την μια κάτω από την άλλη.


import numpy as np
import matplotlib.pyplot as plt

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

Παρατηρήστε ότι η εντολή subplot() παίρνει σαν όρισμα έναν ακέραιο αριθμό ο οποίος καθορίζει πως θα εμφανιστούν οι γραφικές παραστάσεις στο παράθυρο γραφικών. Τα δύο πρώρα ψηφία είναι ο αριθμός των γραμμών και στηλών και το τελευταίο ψηφίο η τρέχουσα γραφική παράστση. Στο συγκεκριμένο παράδειγμα έχουμε δυο γραμμές και μια στήλη, δηλαδή μια γραφική παράσταση πάνω από την άλλη. Δείτε ακόμα ότι η εντολή figure() παίρνει ως όρισμα το παράθυρο γραφικών στο οποίο τοποθετούμε τις γραφικές παραστάσεις. Μια και εδώ έχουμε μόνο ένα παράθυρο γραφικών, η συγκεκριμένη εντολή είναι περιττή και μπορεί να παραληφθεί.

Τρισδιάστατες γραφικές παραστάσεις

Για τη δημιουργία τρισδιάστατων γραφικών παραστάσεων, πέρα από την εντολή import matplotlib.pyplot as plt απαιτείται και η προσθήκη της εντολής from mpl_toolkits.mplot3d import Axes3D (το πακέτο mplot3d περιέχει τις εντολές για την δημιουργία των τρισδιάστατων γραφικών). Έτσι, οι πρώτες εντολές ενός προγράμματος που σχεδιάζει γραφικά στις τρείς διαστάσεις είναι συνήθως οι ακόλουθες:


import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

Ως πρώτο παράδειγμα θα δούμε πως μπορούμε να οπτικοποιήσουμε ένα σύνολο σημείων στις 3 διαστάσεις (ένα λεγόμενο σμήνος σημειών). Στο πρόγραμμα που ακολουθεί παράγουμε 100 τυχαία σημεία με συνιστώσες $(x_i, y_i, z_i)$, $i=0,\ldots,99$, και τέτοια ώστε $23 \le x_i \lt 32$, $0 \le y_i \lt 100$, $-25 \le z_i \lt 25$. Τα σημειώνουμε στον τρισδιάστατο χώρο με σφαίρες χρώματος μπλέ.


import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

def randrange(n, vmin, vmax):
    return (vmax-vmin)*np.random.rand(n) + vmin

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

n = 100

xs = randrange(n, 23, 32)
ys = randrange(n, 0, 100)
zs = randrange(n, -25, 25)

ax.scatter(xs, ys, zs, c='b', marker='o')

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

plt.show()

Παρατηρήστε ότι η εντολή που σχεδιάζει τα παραπάνω σημεία είναι η scatter(), η οποία, πέρα από τις συντεταγμές των σημείων που σχεδιάζουμε παίρνει και δύο επιπέον ορίσματα, το χρώμα (c, color) και το είδος (m, marker) των σημείων. Σαν άσκηση, αλλάξτε τον παραπάνω κώδικα έτσι ώστε τα πρώτα 50 σημερεία να σημειώνονται με κόκκινα τετραγωνάκια και τα υπόλοιπα με μαύρους κύκλους. Δείτε επίσης ότι σημειώνουμε τους τρείς άξονες για τον καλύτερο προσανατολισμό στον χώρο, ενώ, όπως πάντα, η τελευταία εντολή στον παραπάνω κώδικα είναι η show() η οποία αμφανίζει τη γραφική παράσταση στην οθόνη του υπολογιστή μας.

Στο επόμενο παράδειγμα ζωγραφίζουμε τη γραφική παράσταση της συνάρτησης $\sin(\sqrt{x^2 + y^2})$ για $-5 \le x, y \le 5$. Όπως και πρίν, κατασκευάζουμε τρία διανύσματα που περιέχουν τις συντεταγμένες ενός αρκετά μεγάλου πλήθους σημείων πάνω στη γραφική παράσταση της συνάρτησης που θέλουμε να οπτικοποιήσουμε και καλούμε τη συνάρτηση plot_wireframe() για τη δημιουργία της γραφικής παράστασης.


from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, x)
Z = np.sin(np.sqrt(X**2 + Y**2))

ax.plot_wireframe(X, Y, Z)

plt.show()

Εδώ αξίζει να σημειωθεί ότι η συνάρτηση wireframe() απαιτεί τα διανύσματα εισόδου να είναι διδιάστατοι πίνακες και αυτό επιτυγχάνεται με την χρήση της εντολής meshgrid() της βιβλιοθήκες NumPy. Μπορούμε να αυξήσουμε ή να μειώσουμε τις διαστάσεις των πινάκων X, Y, και Ζ αλλάζοντας την τελευταία παράμετρο στην εντολή linspace().

Μπορούμε επίσης να χρησιμοποιήσουμε την εντολή plot_surface() αντί της plot_wireframe() έτσι ώστε η επιφάνεια να χρωματιστεί ανάλογα την $Z$-συντεταγμένη και θα παράξει το σχήμα το οποίο εμφανίζεται στα δεξιά. Δείτε επίσης ότι στα δεξιά του γραφήματος εμφανίζεται και ένας χρωματικός οδηγός για τις $Z$-συντεταγμένες του γραφήματος (το λεγόμενο colorbar). Ο χρήστης μπορεί φυσικά να αυξήσει ή να μειώσει τον αριθμό των σημείων (όπως στο προηγούμενο παράδειγμα), να αλλάξει την κλίμακα στους τρεις άξονες και, τέλος, να επιλέξει διαφορετική παλέτα χρωμάτων από αυτή που χρησιμοποιήσαμε για το συγκεκριμένο γράφημα. Ο κώδικας που χρησιμοποιήσαμε για τη συγκεκριμένη γραφική παράσταση φαίνεται παρακάτω.


from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = np.linspace(-5, 5, 250)
X, Y = np.meshgrid(x, x)
Z = np.sin(np.sqrt(X**2 + Y**2))

surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)

ax.set_zlim(-1.01, 1.01)

fig.colorbar(surf, shrink=0.5, aspect=5)

plt.show()

Ο ενδιαφερόμενος αναγνώστης μπορεί να βρεί περισσότερες πληροφορίες και για άλλα είδη (τρισδιάτατων) γραφικών παραστάσεων που μπορεί να δημιουργήσει με την matplotlib στη διεύθυνση http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html. Κλείνουμε με το γράφημα των ισοϋψών καμπυλών της επιφάνειας $z = \sin(3x) \cos(x+y)$ στο χωρίο $[-3,3]\times[−3,3]$.

Μπορείτε να πειραματιστείτε με τους κώδικες που παράγουν τις παραπάνω γραφικές παραστάσεις χρησιμοποιώντας τον κώδικα mysurf3d.py για τις γραφικές παραστάσεις επιφανειών χρωματισμένες ανάλογα με το ύψος τους, τον κώδικα mycont.py για τις γραφικές παραστάσεις με ισοϋψείς καμπύλες, τον κώδικα wire3d_demo.py για τις γραφικές παραστάσεις επιφανειών και τον κώδικα scatter3d_demo.py για την οπτικοποίηση σημείων.