Πώς να ενσωματώσετε διαδραστικές απεικονίσεις Python στον ιστότοπό σας με το Python και το Matplotlib

Σε ένα προηγούμενο σεμινάριο freeCodeCamp, εξήγησα πώς να δημιουργήσω αυτόματες ενημερώσεις οπτικοποιήσεων δεδομένων στο Python.

Ορισμένοι αναγνώστες απάντησαν για να ρωτήσουν εάν υπήρχε τρόπος να κάνουν τις οπτικοποιήσεις διαδραστικές. Ευτυχώς, υπάρχει ήδη μια εύκολη λύση!

Σε αυτό το σεμινάριο, θα σας διδάξω πώς μπορείτε να δημιουργήσετε διαδραστική οπτικοποίηση δεδομένων στο Python. Αυτές οι απεικονίσεις είναι εξαιρετικοί υποψήφιοι για ενσωμάτωση στο ιστολόγιο ή στον ιστότοπό σας.

Η συγκεκριμένη οπτικοποίηση δεδομένων με την οποία εργαζόμαστε

Αντί να δημιουργήσουμε μια ολόκληρη οπτικοποίηση δεδομένων από το μηδέν σε αυτό το άρθρο, θα συνεργαστούμε με την οπτικοποίηση που δημιουργήσαμε στο τελευταίο μου σεμινάριο.

Η οπτικοποίηση χρησιμοποιεί pandas, matplotlib και Python για να παρουσιάσει διάφορα σημεία δεδομένων από τις 5 μεγαλύτερες δημόσιες τράπεζες στις Ηνωμένες Πολιτείες.

Ακολουθεί μια στατική εικόνα της οπτικοποίησης που δημιουργήσαμε:

Ο πραγματικός κώδικας για την οπτικοποίηση περιλαμβάνεται παρακάτω. Αυτό το καλύψαμε στο τελευταίο σεμινάριο, αλλά λάβετε υπόψη ότι θα χρειαστεί να δημιουργήσετε το δικό σας IEX Cloud API κλειδί και να το συμπεριλάβετε στη IEX_API_Keyμεταβλητή για να λειτουργήσει το σενάριο.

######################## #Import dependencies ######################## import pandas as pd import matplotlib.pyplot as plt ######################## #Import and clean data ######################## IEX_API_Key = '' tickers = [ 'JPM', 'BAC', 'C', 'WFC', 'GS', ] #Create an empty string called `ticker_string` that we'll add tickers and commas to ticker_string = '' #Loop through every element of `tickers` and add them and a comma to ticker_string for ticker in tickers: ticker_string += ticker ticker_string += ',' #Drop the last comma from `ticker_string` ticker_string = ticker_string[:-1] #Create the endpoint and years strings endpoints = 'chart' years = '5' #Interpolate the endpoint strings into the HTTP_request string HTTP_request = f'//cloud.iexapis.com/stable/stock/market/batch?symbols={ticker_string}&types={endpoints}&range={years}y&cache=true&token={IEX_API_Key}' #Send the HTTP request to the IEX Cloud API and store the response in a pandas DataFrame bank_data = pd.read_json(HTTP_request) #Create an empty list that we will append pandas Series of stock price data into series_list = [] #Loop through each of our tickers and parse a pandas Series of their closing prices over the last 5 years for ticker in tickers: series_list.append(pd.DataFrame(bank_data[ticker]['chart'])['close']) #Add in a column of dates series_list.append(pd.DataFrame(bank_data['JPM']['chart'])['date']) #Copy the 'tickers' list from earlier in the script, and add a new element called 'Date'. #These elements will be the column names of our pandas DataFrame later on. column_names = tickers.copy() column_names.append('Date') #Concatenate the pandas Series togehter into a single DataFrame bank_data = pd.concat(series_list, axis=1) #Name the columns of the DataFrame and set the 'Date' column as the index bank_data.columns = column_names bank_data.set_index('Date', inplace = True) ######################## #Create the Python figure ######################## #Set the size of the matplotlib canvas fig = plt.figure(figsize = (18,8)) ################################################ ################################################ #Create subplots in Python ################################################ ################################################ ######################## #Subplot 1 ######################## plt.subplot(2,2,1) #Generate the boxplot plt.boxplot(bank_data.transpose()) #Add titles to the chart and axes plt.title('Boxplot of Bank Stock Prices (5Y Lookback)') plt.xlabel('Bank') plt.ylabel('Stock Prices') #Add labels to each individual boxplot on the canvas ticks = range(1, len(bank_data.columns)+1) labels = list(bank_data.columns) plt.xticks(ticks,labels) ######################## #Subplot 2 ######################## plt.subplot(2,2,2) #Create the x-axis data dates = bank_data.index.to_series() dates = [pd.to_datetime(d) for d in dates] #Create the y-axis data WFC_stock_prices = bank_data['WFC'] #Generate the scatterplot plt.scatter(dates, WFC_stock_prices) #Add titles to the chart and axes plt.title("Wells Fargo Stock Price (5Y Lookback)") plt.ylabel("Stock Price") plt.xlabel("Date") ######################## #Subplot 3 ######################## plt.subplot(2,2,3) #Create the x-axis data dates = bank_data.index.to_series() dates = [pd.to_datetime(d) for d in dates] #Create the y-axis data BAC_stock_prices = bank_data['BAC'] #Generate the scatterplot plt.scatter(dates, BAC_stock_prices) #Add titles to the chart and axes plt.title("Bank of America Stock Price (5Y Lookback)") plt.ylabel("Stock Price") plt.xlabel("Date") ######################## #Subplot 4 ######################## plt.subplot(2,2,4) #Generate the histogram plt.hist(bank_data.transpose(), bins = 50) #Add a legend to the histogram plt.legend(bank_data.columns,fontsize=10) #Add titles to the chart and axes plt.title("A Histogram of Daily Closing Stock Prices for the 5 Largest Banks in the US (5Y Lookback)") plt.ylabel("Observations") plt.xlabel("Stock Prices") plt.tight_layout() ################################################ #Save the figure to our local machine ################################################ plt.savefig('bank_data.png')

Τώρα που έχουμε κατανοήσει τη συγκεκριμένη οπτικοποίηση με την οποία συνεργαζόμαστε, ας μιλήσουμε για το τι σημαίνει μια οπτικοποίηση να είναι διαδραστική.

Τι σημαίνει για μια διαδραστική απεικόνιση;

Υπάρχουν δύο τύποι οπτικοποιήσεων δεδομένων που είναι χρήσιμες για ενσωμάτωση στον ιστότοπό σας.

Ο πρώτος τύπος είναι μια στατική απεικόνιση. Αυτή είναι βασικά μια εικόνα - σκεφτείτε .pngή .jpgαρχεία.

Ο δεύτερος τύπος είναι μια δυναμική απεικόνιση. Αυτές οι απεικονίσεις αλλάζουν σε απόκριση στη συμπεριφορά των χρηστών, συνήθως με μετακίνηση ή ζουμ. Οι δυναμικές απεικονίσεις δεν αποθηκεύονται σε αρχεία .pngή .jpgαρχεία, αλλά συνήθως σε ετικέτες svgή iframe.

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

  1. Θα κάνετε κλικ σε ένα κουμπί κάτω αριστερά για να ενεργοποιήσετε τη δυναμική λειτουργία.
  2. Μόλις ενεργοποιηθεί η δυναμική λειτουργία, μπορείτε να κάνετε ζουμ και να μετακινήσετε την οπτικοποίηση με το ποντίκι σας.
  3. Μπορείτε επίσης να περικόψετε και να κάνετε ζουμ σε μια συγκεκριμένη ενότητα της οπτικοποίησης.

Στην επόμενη ενότητα αυτού του σεμιναρίου, θα μάθετε πώς να εγκαταστήσετε και να εισαγάγετε τη mpld3βιβλιοθήκη, η οποία είναι η εξάρτηση Python που θα χρησιμοποιήσουμε για να δημιουργήσουμε τα διαδραστικά μας γραφήματα.

Τρόπος εισαγωγής της βιβλιοθήκης mpld3

Για να χρησιμοποιήσετε τη mpld3βιβλιοθήκη στην εφαρμογή μας Python, υπάρχουν δύο βήματα που πρέπει πρώτα να ολοκληρώσουμε:

  1. Εγκαταστήστε τη mpld3βιβλιοθήκη στο μηχάνημα στο οποίο εργαζόμαστε.
  2. Εισαγάγετε τη mpld3βιβλιοθήκη στο σενάριό μας Python.

Αρχικά, ας εγκαταστήσουμε mpld3στον τοπικό υπολογιστή μας.

Ο ευκολότερος τρόπος για να το κάνετε αυτό είναι να χρησιμοποιήσετε το pipπρόγραμμα διαχείρισης πακέτων για το Python3. Εάν έχετε ήδη pipεγκαταστήσει στον υπολογιστή σας, μπορείτε να το κάνετε εκτελώντας την ακόλουθη δήλωση από τη γραμμή εντολών σας:

pip3 install mpld3

Τώρα που mpld3είναι εγκατεστημένο στο μηχάνημά μας, μπορούμε να το εισαγάγουμε στο σενάριο Python με την ακόλουθη δήλωση:

import mpld3

Για λόγους αναγνωσιμότητας, θεωρείται βέλτιστη πρακτική να συμπεριλαμβάνετε αυτήν την εισαγωγή μαζί με τις υπόλοιπες εισαγωγές σας στην κορυφή του σεναρίου σας. Αυτό σημαίνει ότι η ενότητα εισαγωγής σας θα έχει τώρα την εξής μορφή:

######################## #Import dependencies ######################## import pandas as pd import matplotlib.pyplot as plt import mpld3

Πώς να μετατρέψετε μια στατική matplotlibαπεικόνιση σε διαδραστική οπτικοποίηση δεδομένων

Η mpld3κύρια λειτουργικότητα της βιβλιοθήκης είναι η λήψη μιας υπάρχουσας matplotlibοπτικοποίησης και η μετατροπή της σε κάποιο κώδικα HTML που μπορείτε να ενσωματώσετε στον ιστότοπό σας.

Το εργαλείο που χρησιμοποιούμε για αυτό είναι mpld3το fig_to_htmlαρχείο, το οποίο δέχεται ένα matplotlibfigureαντικείμενο ως μοναδικό όρισμα και επιστρέφει HTML.

Για να χρησιμοποιήσετε τη fig_to_htmlμέθοδο για το σκοπό μας, απλώς προσθέστε τον ακόλουθο κώδικα στο τέλος του σεναρίου Python:

html_str = mpld3.fig_to_html(fig) Html_file= open("index.html","w") Html_file.write(html_str) Html_file.close()

Αυτός ο κώδικας δημιουργεί το HTML και το αποθηκεύει κάτω από το όνομα αρχείου index.htmlστον τρέχοντα κατάλογο εργασίας σας. Δείτε πώς φαίνεται όταν αποδίδεται σε μια ιστοσελίδα:

Όταν τοποθετείτε το δείκτη του ποντικιού πάνω από αυτήν την οπτικοποίηση, τρία εικονίδια θα εμφανιστούν κάτω αριστερά. Το αριστερό εικονίδιο επιστρέφει την οπτικοποίηση στην προεπιλεγμένη του εμφάνιση. Το μεσαίο εικονίδιο επιτρέπει τη δυναμική λειτουργία. Το δεξί εικονίδιο σάς επιτρέπει να περικόψετε και να κάνετε ζουμ σε ένα συγκεκριμένο σημείο στην οπτικοποίηση.

Ένα κοινό σφάλμα κατά την εργασία με τα pandas και το mpld3

Κατά τη δημιουργία της διαδραστικής οπτικοποίησης σε αυτό το σεμινάριο, ενδέχεται να συναντήσετε το ακόλουθο σφάλμα που δημιουργήθηκε από mpld3:

TypeError: array([ 1.]) is not JSON serializable

Ευτυχώς, υπάρχει μια καλά τεκμηριωμένη λύση σε αυτό το σφάλμα στο GitHub.

Πρέπει να επεξεργαστείτε το αρχείο _display.py που βρίσκεται στο Lib \ site-package \ mpld3 και να αντικαταστήσετε την κλάση NumpyEncoder από αυτήν:

class NumpyEncoder(json.JSONEncoder): """ Special json encoder for numpy types """ def default(self, obj): if isinstance(obj, (numpy.int_, numpy.intc, numpy.intp, numpy.int8, numpy.int16, numpy.int32, numpy.int64, numpy.uint8, numpy.uint16,numpy.uint32, numpy.uint64)): return int(obj) elif isinstance(obj, (numpy.float_, numpy.float16, numpy.float32, numpy.float64)): return float(obj) try: # Added by ceprio 2018-04-25 iterable = iter(obj) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return json.JSONEncoder.default(self, obj)

Μόλις γίνει αυτή η αντικατάσταση, τότε ο κώδικάς σας θα πρέπει να λειτουργεί σωστά και το index.htmlαρχείο σας θα δημιουργηθεί με επιτυχία.

Τελικές σκέψεις

Σε αυτό το σεμινάριο, μάθατε πώς να δημιουργείτε διαδραστικές απεικονίσεις δεδομένων στο Python χρησιμοποιώντας τις βιβλιοθήκες matplotlib και mpld3. Ακολουθεί μια συγκεκριμένη περίληψη αυτού που καλύψαμε:

  1. Ο ορισμός μιας δυναμικής οπτικοποίησης δεδομένων
  2. Πώς να εγκαταστήσετε και να εισαγάγετε τη mpld3βιβλιοθήκη για το Python
  3. Πώς να χρησιμοποιήσετε τη mpld3βιβλιοθήκη για να μετατρέψετε μια matplotlibοπτικοποίηση σε μια δυναμική απεικόνιση που μπορείτε να ενσωματώσετε στον ιστότοπό σας
  4. Πώς να διορθώσετε ένα κοινό σφάλμα που mpld3αντιμετωπίζουν οι χρήστες της βιβλιοθήκης

Αυτό το σεμινάριο γράφτηκε από τον Nick McCullum, ο οποίος διδάσκει Python και ανάπτυξη JavaScript στον ιστότοπό του.