Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Widgeturi Matplotlib

Matplotlib isn’t only for static plots. While GUIs are typically created with GUI libraries and frameworks such as PyQt, Tkinter, disperat și wxPythonși în timp ce Python are o integrare excelentă cu PyQt, Tkinter și wxPython – there’s no need to use any of these for some basic GUI functionality, through Widgeturi Matplotlib.

matplotlib.widgets modulul are mai multe clase, inclusiv AxesWidget, din care Buttons, CheckButtons, Sliders, TextBoxes, etc sunt derivate. Toate acestea acceptă Axes they’re being added to as the one and only mandatory constructor argument, and their positioning has to be manually set. A thing to note is that the widget-ul este axele, so you’ll create an Axes exemplu pentru fiecare widget.

Un alt lucru de remarcat este că trebuie să păstrați referințele la widget-uri altfel, s-ar putea strânge gunoiul.

Fiecare dintre ele poate fi, de asemenea, dezactivat prin setare active la False, in which case, they won’t respond to any events, such as being clicked on. That being said, we can introduce a new type of interactivity to our plots, through various GUI elements and components.

Notă: Matplotlib isn’t meant to be used for high-quality GUI creation, nor user-friendly systems. These widgets are rudimentary, don’t really look great and have limited functionality. They’re meant as a way to prototype and test things out, rather than actually ship them.

If you’ve worked with PyQt before – you might notice that the general syntax and approach to adding these widgets, as well as connecting them to event handlers is fairly familiar.

Adăugarea de butoane

Să începem cu butoane - matplotlib.widgets modulul definește a Button clasă. Pentru a vă conecta la el, numim on_clicked() funcția, care execută funcția pe care o furnizăm. Odată ce a fost detectat un clic, funcția se execută.

În timpul creării butonului, atribuim un Axes la acesta, folosit pentru poziționare. Putem trece și într-un label la acel moment, pentru a adăuga ceva text și a-l adnota pentru un utilizator. The color și hovercolor arguments define the color of the button before and after it’s being hovered over.

Since we take care of the positioning and space for all widgets – let’s create a Figure și Axes, allow for some spacing at the bottom to add a button, and plot an empty Scatter Plot. Then, we’ll define an EventHandler clasa, care are o singură metodă add_random(). Metoda generează două numere aleatoare și trasează un marcator pentru ele pe Axes we’ve created before and calls plt.draw(), care redesenează Figure. When updating plots, we’ll always have to call plt.draw() din nou pentru a-l actualiza efectiv:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)
plot = ax.scatter([], []) class EventHandler: def add_random(self, event): x = np.random.randint(0, 100) y = np.random.randint(0, 100) ax.scatter(x, y) plt.draw() # Axes for the Button and positioning
# xposition and yposition in percentages, width, height
button_ax = plt.axes([0.7, 0.05, 0.2, 0.07])
# Create Button and assign it to `button_ax` with label
button = Button(button_ax, 'Add Random', color='green', hovercolor='red')
# On a detected click, execute add_random()
button.on_clicked(EventHandler().add_random) plt.show()

Acest lucru are ca rezultat un Figure, cu un gol Axes în interiorul acestuia și un buton în colțul din dreapta sus al ecranului, în sine Axes:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Și după ce am apăsat butonul de câteva zeci de ori, nostru ax va fi populat cu marcatori aleatori:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

În termeni mai practici, am putea crea un ciclu de caracteristici pentru a fi reprezentate la fiecare apăsare de buton. Acest lucru necesită câteva modificări ale EventHandler, precum și un alt buton pentru a reveni prin acel ciclu.

Să folosim Calitate Vin Roșu set de date din nou și vizualizați mai multe caracteristici față de Alcool feature. Since we can’t be bothered to plot these individually by writing the code to plot one feature against the other, and then modifying that code to plot another feature against the other.

Creating a Scatter Matrix might help us here, but if the dataset has a lot of features, it’ll be fairly unreadable and we won’t get far. If you’d like to have atât parcele la scară mare pe care le puteți vizualiza și interpreta cu ușurință, de asemenea as having multiple features cycling through without any extra effort – you can automate this process with buttons:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import Button fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2) df = pd.read_csv('winequality-red.csv')
plot = ax.scatter([], []) class EventHandler: i = 0 # Find and plot next feature, re-draw the Axes def next_feature(self, event): # If the counter is at the end of the columns # Revert it back to 0 to cycle through again if self.i >= len(df.columns): self.i = 0 # Clear Axes from last plot ax.cla() # Plot a feature against a feature located on the `i` column ax.scatter(df['alcohol'], df.iloc[:,self.i]) # Set labels ax.set_xlabel('Alcohol') ax.set_ylabel(df.columns[self.i]) # Increment i self.i += 1 # Update Figure plt.draw() def previous_feature(self, event): # If the counter is at the start of the columns # Revert it back to the last column to cycle through if self.i <= 0: self.i = len(df.columns)-1 ax.cla() ax.scatter(df['alcohol'], df.iloc[:,self.i]) ax.set_xlabel('Alcohol') ax.set_ylabel(df.columns[self.i]) self.i -= 1 plt.draw() # Add buttons
button1_ax = plt.axes([0.7, 0.02, 0.2, 0.07])
next_button = Button(button1_ax, 'Next Feature')
next_button.on_clicked(EventHandler().next_feature) button2_ax = plt.axes([0.45, 0.02, 0.2, 0.07])
previous_button = Button(button2_ax, 'Previous Feature')
previous_button.on_clicked(EventHandler().previous_feature) plt.show()

EventHandler class now has two methods – next_feature() și previous_feature(). Ambele verifică dacă contorul i has reached the end or start of the column list – and to avoid an IndexError, resetăm indicele la valoarea opusă și simulăm a ciclu. Mergând mai jos 0 ne va duce înapoi la capăt din lista de coloane și trecerea peste ultima coloană ne va reveni la prima.

After ascertaining where we’re located – we ștergeți Axes, since we’d be plotting again on top of an existing plot without clearing it via cla() (clureche axes). Alternativ, puteți îngrămădi și relații de caracteristici, prin trasarea unul peste celălalt și folosind cla() declarație la resetarea indexului la sfârșitul/începutul ciclului.

După curățarea Axes – we’ve got a cleared canvas to paint on with the ax.scatter() funcţie. În acest exemplu, caracteristica fixă ​​este Alcool, so it’s present at all times. The other feature varies, and can be accessed through iloc[], trecând în indexul coloanei. Aceasta returnează a Series pe care îl putem folosi în acest complot. În mod similar, putem accesa nume de coloane through their index as well – df.columns[index], care este folosit pentru a seta eticheta axei Y.

În cele din urmă, creștem/scădem contorul și sunăm plt.draw() pentru a actualiza Figure:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Odată ce facem clic pe Următoarea caracteristică butonul, următoarea caracteristică din lista de coloane va fi reprezentată în funcție de Alcool, Şi Figure will be appropriately updated – the labels, markers and scale. The same goes the other way around – Caracteristica anterioară va parcurge lista în direcția opusă, permițându-ne să pedalăm înainte și înapoi, cu un mecanism de siguranță care ne resetează contorul de fiecare dată când ajungem la sfârșitul sau începutul ciclului.

Adăugarea de butoane radio și casete de selectare

Butoane radio sunt folosite pentru a permite unui utilizator să selecteze o singură valoare din mai multe valori. Numai un singur buton radio poate fi selectat la un moment dat și, de obicei, reprezintă o alegere. Casete de bifare can be used if you’d like to let the user select multiple options at once.

Notă: Există o capacitate foarte limitată de a verifica dacă o casetă de selectare este on or de pe. In fact, there’s none out of the box. You can only ever check if the box is presat or nu, ceea ce reprezintă o limitare serioasă a modului în care poate fi utilizat, deoarece nu avem idee în ce stare se afla înainte. Singura alternativă este să vă păstrați propriul contor/verificare cu privire la starea curentă a casetei cu un boolean și să modificați logica pe baza acestuia.

Acest lucru vă va permite, de exemplu, să adăugați o casetă de selectare pentru fiecare argument de personalizare a unei anumite parcele, permițând utilizatorului să le stabilească True or False (bifat sau nebifat) sau orice altă mapare neconflictuală bazată pe aceste stări.

Though, since the API is limited itself, we’ll limit ourselves to the intended usage as well – turning things on and off. We’ll have two features, that we can turn on și de pe via a Checkbox. Note that even this functionality is limited to objects for which you can check if they’re visible or not.

On the other hand, we don’t want to allow the user to apply two scales at once, or to set two X-limits at once, since only the statement called second in the sequence would be applied. For these – we’d use Radio Buttons.

Let’s add a couple of Radio Buttons to let the user select the axis range via a couple of Radio Buttons, but also allow them turn feature visualizations on și de pe:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons
from matplotlib.widgets import RadioButtons fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2) df = pd.read_csv('winequality-red.csv') # Plot two line plots for two features, and turn them invisible
line1, = ax.plot(df['fixed acidity'], visible=False)
line2, = ax.plot(df['citric acid'], visible=False) class EventHandler: # set_range handler def set_range(label): if (label == 'Small Range'): ax.set_xlim(0, 1600) ax.set_ylim(0, 25) else: ax.set_xlim(0, 1600) ax.set_ylim(0, 50) plt.draw() # Turn off, if on, and on if off def apply_features(label): if (label == 'Fixed Acidity'): line1.set_visible(not line1.get_visible()) elif (label == 'Citric Acid'): line2.set_visible(not line2.get_visible()) plt.draw() # Add radio buttons and checkboxes
ranges_ax = plt.axes([0.7, 0.02, 0.2, 0.1])
range_radio_buttons = RadioButtons(ranges_ax, ('Small Range', 'Large Range'))
range_radio_buttons.on_clicked(EventHandler.set_range) checkboxes_ax = plt.axes([0.4, 0.02, 0.25, 0.1])
checkboxes = CheckButtons(checkboxes_ax, ('Fixed Acidity', 'Citric Acid'))
checkboxes.on_clicked(EventHandler.apply_features) plt.show()

Again, we’ve got two methods in the EventHandler() class – set_range() și apply_features(). set_range() method sets the range to either “small” or “large”, by adjusting the Axes‘ X and Y-limits. The apply_features() funcția modifică visible câmpul Line Plots pe care le-am făcut mai devreme, pe baza curentului lor visible stare. Dacă visible == True, dezactivăm Line Plot și invers.

We have to rely on the built-in ability to check the visibility of Line Plots, since we can’t check if the checkbox was checked or not before. This same ability can be emulated with a status boolean în domeniul de aplicare al EventHandler() clasa, care este setată la True și False on every click, for plot types that don’t support checking if they’re visible out of the box.

Rularea acestui cod are ca rezultat a Figure cu două seturi de nasturi în partea de jos. Dacă bifam ambele casete de selectare, vor apărea ambele diagrame de linii:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Le putem dezactiva individual:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Și putem schimba intervalul Axes prin butoanele radio:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Adăugarea casetelor de text

Casete de text sunt obisnuiti sa colecta data from the user – and we can alter the plots based on this data. For example, we can ask a user to input the name of a feature, or to insert a function for our plot to visualize. Of course, working with user input can be tricky – there are always edge cases to look out for.

Let’s write a script that allows the user to input a numele caracteristicii a unui set de date și Axes updates on each submission to reflect the input. For the convenience of the user, we’ll let them know if the input couldn’t be matched with a column name:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import TextBox fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2) df = pd.read_csv('winequality-red.csv') class EventHandler: def submit(feature_name): if feature_name != "" or feature_name != None: if feature_name in df: ax.cla() ax.plot(df[feature_name]) else: if len(textbox_ax.texts) > 2: del textbox_ax.texts[-1] textbox_ax.text(-2, 0.4, feature_name + ' was not found.') plt.draw() textbox_ax = plt.axes([0.7, 0.02, 0.2, 0.1])
textbox = TextBox(textbox_ax, 'Feature Name')
textbox.on_submit(EventHandler.submit) plt.show()

Avem o verificare simplă pentru a vedea dacă este furnizat feature_name este gol sau None, in which case, we don’t do anything. If not, we check if the feature_name este prezent în DataFrame, attaching a message that the feature wasn’t found if it’s not present. Before attaching the text though, we have to make sure that the previous message is removed, so that the new one doesn’t overlap with it. The axes.texts proprietatea este o listă a tuturor Text instanțe pe an Axes. Deoarece Axes are deja un Text de exemplu, aparținând nostru TextBox, we don’t want to remove anything if there are 2 or less Text instances present – the error message and the TextBox eticheta.

If above two, we’ve already got an error message, which should be removed.

Dacă caracteristica is prezent în DataFrame, totuși, ștergem Axes si traseaza-l:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Adăugarea selectoarelor de interval

Selectoare de interval can be used to allow the user to select a span of data and focus on it, setting the axis limits based on that selection. By default, many libraries support this functionality, though unfortunately, Matplotlib doesn’t and we’ll have to do this manually. Additionally, we’ll have to add an extra „Reset“ butonul dacă vrem a micsora de asemenea.

Pentru a adăuga un Selector de interval, we don’t need to dedicate an entire new Axes for it – we can attach it to an existing one, which makes a lot of sense. When generating a SpanSelector, furnizăm Axes îi aparține, precum și handler-ului de evenimente, urmat de 'horizontal' or 'vertical', care rotește Axes și Selectorul de intervale ambele.

useblit argumentul este de obicei setat la True because it enhances performance on most backends. Additionally, we’ve added a few styling properties, such as setting the alpha a dreptunghiului creat ca selector de interval pentru 0.5 si facecolor la un frumos tab:blue:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
from matplotlib.widgets import Button fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2) df = pd.read_csv('AmesHousing.csv') ax.scatter(x = df['Year Built'], y = df['Total Bsmt SF'], alpha = 0.6) class EventHandler: def select_horizontal(x, y): ax.set_xlim(x, y) plt.draw() def reset(self): ax.set_xlim(df['Year Built'].min(), df['Year Built'].max()) plt.draw span_horizontal = SpanSelector(ax, EventHandler.select_horizontal, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='tab:blue')) button_ax = plt.axes([0.7, 0.02, 0.2, 0.07])
button = Button(button_ax, 'Reset')
button.on_clicked(EventHandler.reset) plt.show()

Rularea acestui lucru generează un grafic pe care putem selecta intervale și mărim pe ele setând Axes-limits la valorile furnizate:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Adăugarea de cursoare

Sliders permite utilizatorilor să aleagă între mai multe valori în mod intuitiv, glisând un marcator și selectând o valoare. În mod obișnuit, glisoarele sunt folosite pentru a actualiza continuu o anumită valoare a unui grafic, cum ar fi intervalul său or chiar și o caracteristică. De exemplu, puteți ajusta valoarea unei constante printr-un glisor, care, la rândul său, afectează o funcție care se bazează pe acea constantă.

Let’s write a script that allows us to change the Y and X-axis limits, through a slider, which will let us change the perspective from which we’re viewing our data:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2, left=0.2) df = pd.read_csv('winequality-red.csv')
plot, = ax.plot(df['volatile acidity']) class EventHandler: def update(val): ax.set_ylim(0, yslider.val) ax.set_xlim(0, xslider.val) plt.draw() xslider_ax = plt.axes([0.35, 0.03, 0.5, 0.07])
xslider = Slider( ax=xslider_ax, label="X-limit", valmin=0, valmax=len(df['volatile acidity']), valinit=len(df['volatile acidity']), orientation="horizontal"
) yslider_ax = plt.axes([0.03, 0.2, 0.07, 0.5])
yslider = Slider( ax=yslider_ax, label="Y-limit", valmin=0, valmax=3, valinit=1.5, orientation="vertical"
) xslider.on_changed(EventHandler.update)
yslider.on_changed(EventHandler.update) plt.show()

We’ve adjusted the padding to allow for a slider on the left and bottom of the Axes, și a trasat un simplu Line Plot. Adăugarea unui glisor necesită să facem un Axes pentru el, la fel ca în cazul majorității celorlalte widget-uri, și atribuiți-l la ax argument al Slider through the constructor. Additionally, we can set the minimum, maximum and initial values of the slider. These will typically be dynamic ranges, based on the data you’re plotting, but can also be manually set scalar values.

În cele din urmă, Sliders can be oriented horizontally or vertically. Since they’re meant to be continually updated via a mouse-swipe – the on_changed() function is used to trigger a response when a user gives input. We’ve tweaked the EventHandler clasa cu o update() funcție care ajustează pur și simplu valorile limitelor X și Y pe baza value a glisoarelor respective.

Rularea acestui cod va produce o diagramă cu două glisoare, pe care le putem folosi pentru a schimba domeniul de aplicare al Axes:

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Widgeturi Matplotlib PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Timestamp-ul:

Mai mult de la Stackabuse