Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Pripomočki Matplotlib

Matplotlib isn’t only for static plots. While GUIs are typically created with GUI libraries and frameworks such as PyQt, Tkinter, Razočaran in wxPython, in čeprav ima Python odlično integracijo s PyQt, Tkinter in wxPython – there’s no need to use any of these for some basic GUI functionality, through Pripomočki Matplotlib.

O matplotlib.widgets modul ima več razredov, vključno z AxesWidget, od tega Buttons, CheckButtons, Sliders, TextBoxes itd. Vsi ti sprejemajo 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 so osi, so you’ll create an Axes primerek za vsak gradnik.

Treba je opozoriti še na to ohraniti morate reference na gradnike v nasprotnem primeru bodo morda dobili odvoz smeti.

Vsako od njih je mogoče z nastavitvijo tudi onemogočiti active do 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.

Opomba: 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.

Dodajanje gumbov

Začnimo z gumbi - za matplotlib.widgets modul definira a Button razred. Za povezavo z njim pokličemo on_clicked() funkcijo, ki izvaja funkcijo, ki jo nudimo. Ko je zaznan klik, se funkcija izvede.

Med ustvarjanjem gumba dodelimo Axes do njega, ki se uporablja za pozicioniranje. Lahko prenesemo tudi v a label takrat, da dodate nekaj besedila in ga označite za uporabnika. The color in 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 in Axes, allow for some spacing at the bottom to add a button, and plot an empty Scatter Plot. Then, we’ll define an EventHandler razred, ki ima eno samo metodo add_random(). Metoda ustvari dve naključni števili in nariše oznako zanju na Axes we’ve created before and calls plt.draw(), ki ponovno nariše Figure. When updating plots, we’ll always have to call plt.draw() znova, da ga dejansko posodobim:

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()

Rezultat tega je Figure, s praznim Axes v njem in gumb v zgornjem desnem kotu zaslona Axes:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

In po pritisku na gumb nekaj desetkrat, naš ax bo zapolnjen z naključnimi oznakami:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

V bolj praktičnem smislu bi lahko ustvarili a cikel značilnosti, ki se izrišejo ob vsakem pritisku gumba. To zahteva nekaj popravkov EventHandlerin še en gumb za vrnitev skozi ta cikel.

Uporabimo Kakovost rdečega vina in vizualizirajte več funkcij v primerjavi z Alkohol 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 tako obsežne ploskve, ki si jih lahko preprosto ogledate in interpretirate, tudi 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()

O EventHandler class now has two methods – next_feature() in previous_feature(). Oba preverjata, ali števec i has reached the end or start of the column list – and to avoid an IndexError, ponastavimo indeks na nasprotno vrednost in simuliramo a cikel. Gremo spodaj 0 nas bo vrnil k konec seznama stolpcev in če gremo nad zadnji stolpec, se vrnemo nazaj na prvega.

After ascertaining where we’re located – we počistite Axes, since we’d be plotting again on top of an existing plot without clearing it via cla() (cluho axes). Lahko pa nakopičite tudi relacije funkcij, tako da narišete eno na drugo in uporabite cla() stavek pri ponastavitvi indeksa na koncu/začetku cikla.

Po čiščenju Axes – we’ve got a cleared canvas to paint on with the ax.scatter() funkcijo. V tem primeru je fiksna funkcija Alkohol, so it’s present at all times. The other feature varies, and can be accessed through iloc[], ki poteka v indeksu stolpca. To vrne a Series ki jih lahko uporabimo v tej ploskvi. Podobno lahko dostopamo imena stolpcev through their index as well – df.columns[index], ki se uporablja za nastavitev oznake osi Y.

Na koncu povečamo/zmanjšamo števec in pokličemo plt.draw() posodobiti Figure:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Ko enkrat kliknemo na Naslednja funkcija bo naslednji element na seznamu stolpcev narisan proti AlkoholIn Figure will be appropriately updated – the labels, markers and scale. The same goes the other way around – Prejšnja funkcija bo prečkal seznam v nasprotni smeri, kar nam bo omogočilo kroženje naprej in nazaj, z varnostnim mehanizmom, ki ponastavi naš števec vsakič, ko pridemo do konca ali začetka cikla.

Dodajanje radijskih gumbov in potrditvenih polj

Radijske tipke se uporabljajo, da uporabniku omogočijo izbiro ena vrednost iz več vrednosti. Naenkrat je mogoče izbrati samo en izbirni gumb, ki običajno predstavlja izbiro. Potrditvena polja can be used if you’d like to let the user select multiple options at once.

Opomba: Obstaja zelo omejena možnost preverjanja, ali je potrditveno polje on or off. In fact, there’s none out of the box. You can only ever check if the box is pritisnjeno or ne, kar predstavlja resno omejitev glede uporabe, saj nimamo pojma, v kakšnem stanju je bil pred tem. Edina alternativa je, da obdržite svoj števec/preverjanje trenutnega stanja polja z logično vrednostjo in na podlagi tega spremenite logiko.

To bi vam omogočilo, da na primer za vsako dodate potrditveno polje argument prilagajanja določene ploskve, kar omogoča uporabniku, da jih nastavi True or False (označeno ali neoznačeno) ali katero koli drugo nekonfliktno preslikavo na podlagi teh stanj.

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 in off 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 in off:

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() razred – set_range() in apply_features(). set_range() method sets the range to either “small” or “large”, by adjusting the Axes‘ X and Y-limits. The apply_features() funkcija spreminja visible polje črtnih ploskev, ki smo jih naredili prej na podlagi njihovega toka visible stanje. če visible == True, izklopimo črtni izris in obratno.

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 logično v obsegu EventHandler() razred, ki je nastavljen na True in False on every click, for plot types that don’t support checking if they’re visible out of the box.

Zagon te kode povzroči a Figure z dvema nizoma gumbov na dnu. Če potrdimo obe potrditveni polji, se bosta prikazali obe liniji:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Lahko jih izklopimo posamično:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

In lahko spremenimo obseg Axes preko radijskih gumbov:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Dodajanje besedilnih polj

Besedilna polja so vajeni zbiranje 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 ime funkcije nabora podatkov in 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()

Imamo preprosto preverjanje, ali je zagotovljeno feature_name je prazna oz None, in which case, we don’t do anything. If not, we check if the feature_name je prisoten v 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 Lastnina je seznam vseh Text primerki na an Axes. Od takrat Axes že ima Text na primer, ki pripada našemu TextBox, we don’t want to remove anything if there are 2 or less Text instances present – the error message and the TextBox nalepka.

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

Če funkcija is Prisotna v DataFrame, vendar počistimo Axes in narišite:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Dodajanje izbirnikov razpona

Izbirniki razpona 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 "Ponastaviti" gumb, če želimo pomanjšanje kot dobro.

Če želite dodati a Izbirnik razpona, 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, dobavljamo Axes pripada, kot tudi upravljalnik dogodkov, ki mu sledi 'horizontal' or 'vertical', ki vrti Axes in Izbirnik razpona oboje.

O useblit argument je običajno nastavljen na True because it enhances performance on most backends. Additionally, we’ve added a few styling properties, such as setting the alpha pravokotnika, ustvarjenega kot izbirnik razpona za 0.5 in facecolor na lepo 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()

Zagon tega ustvari risbo, na kateri lahko izberemo razpone in jih povečamo tako, da nastavimo meje osi na podane vrednosti:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Dodajanje drsnikov

Sliders omogočajo uporabnikom, da intuitivno izbirajo med številnimi vrednostmi tako, da drsijo oznako in izberejo vrednost. Običajno se drsniki uporabljajo za nenehno posodabljanje neke vrednosti na grafu, kot je njen obseg or celo lastnost. Z drsnikom lahko na primer prilagodite vrednost konstante, kar posledično vpliva na funkcijo, ki je odvisna od te konstante.

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, in narisal preprost črtni izris. Dodajanje drsnika zahteva, da naredimo Axes zanj, kot pri večini drugih gradnikov, in ga dodelite ax trditev 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.

Končno, 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 razred z an update() funkcijo, ki preprosto prilagodi vrednosti meja X in Y na podlagi value ustreznih drsnikov.

Zagon te kode bo ustvaril graf z dvema drsnikoma, ki ju lahko uporabimo za spreminjanje obsega Axes:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Časovni žig:

Več od Stackabuse