Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Matplotlib-widgets

Matplotlib er ikke bare for statiske plott. Mens GUIer vanligvis lages med GUI-biblioteker og rammeverk som f.eks PyQt, Tkinter, Skuffet og wxPython, og mens Python har utmerket integrasjon med PyQt, Tkinter og wxPython - det er ikke nødvendig å bruke noen av disse for noen grunnleggende GUI-funksjonalitet, gjennom Matplotlib-widgets.

De matplotlib.widgets modulen har flere klasser, inkludert AxesWidget, hvorav Buttons, CheckButtons, Sliders, TextBoxes, etc er avledet. Disse aksepterer alle Axes de blir lagt til som det eneste obligatoriske konstruktørargumentet, og deres plassering må angis manuelt. En ting å merke seg er at widget er aksene, så du oppretter en Axes forekomst for hver widget.

En annen ting å merke seg er at du må beholde referanser til widgetene ellers kan de få søppel samlet.

Hver av dem kan også deaktiveres ved innstilling active til False, i så fall vil de ikke svare på noen hendelser, for eksempel å bli klikket på. Når det er sagt, kan vi introdusere en ny type interaktivitet til plottene våre, gjennom ulike GUI-elementer og komponenter.

OBS: Matplotlib er ikke ment å brukes til høykvalitets GUI-oppretting, og heller ikke brukervennlige systemer. Disse widgetene er rudimentære, ser egentlig ikke bra ut og har begrenset funksjonalitet. De er ment som en måte å prototyper og teste ting ut, i stedet for å sende dem.

Hvis du har jobbet med PyQt før - vil du kanskje legge merke til at den generelle syntaksen og tilnærmingen til å legge til disse widgetene, samt koble dem til hendelsesbehandlere, er ganske kjent.

Legge til knapper

La oss begynne med knapper - Den matplotlib.widgets modul definerer en Button klasse. For å koble til den, ringer vi til on_clicked() funksjon, som utfører funksjonen vi leverer. Når et klikk er oppdaget, kjøres funksjonen.

Mens vi oppretter knappen, tildeler vi en Axes til den, brukt til posisjonering. Vi kan også bestå i en label på den tiden, for å legge til litt tekst og kommentere den for en bruker. De color og hovercolor argumenter definerer fargen på knappen før og etter at den holdes over.

Siden vi tar oss av plassering og plass til alle widgets – la oss lage en Figure og Axes, tillate litt mellomrom nederst for å legge til en knapp, og plott et tomt spredningsplott. Deretter vil vi definere en EventHandler klasse, som har en enkelt metode add_random(). Metoden genererer to tilfeldige tall, og plotter en markør for dem på Axes vi har laget før og ringer plt.draw(), som tegner på nytt Figure. Ved oppdatering av tomter må vi alltid ringe plt.draw() igjen for å faktisk oppdatere den:

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

Dette resulterer i en Figure, med en tom Axes innsiden av den og en egen knapp øverst til høyre på skjermen Axes:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Og etter å ha trykket på knappen et par dusin ganger, vår ax vil fylles ut med tilfeldige markører:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Mer praktisk kan vi lage en syklus funksjoner som plottes ved hvert knappetrykk. Dette krever noen justeringer av EventHandler, samt en annen knapp for å gå tilbake gjennom den syklusen.

La oss bruke Rødvin kvalitet datasettet igjen, og visualiser flere funksjoner mot Alkohol trekk. Siden vi ikke gidder å plotte disse individuelt ved å skrive koden for å plotte en funksjon mot den andre, og deretter endre den koden for å plotte en annen funksjon mot den andre.

Å lage en scatter-matrise kan hjelpe oss her, men hvis datasettet har mange funksjoner, vil det være ganske uleselig, og vi kommer ikke langt. Hvis du vil ha både storskala tomter som du enkelt kan se og tolke, også som å ha flere funksjoner som går gjennom uten ekstra innsats – du kan automatisere denne prosessen med knapper:

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

De EventHandler klasse har nå to metoder – next_feature() og previous_feature(). Begge disse sjekker om telleren i har nådd slutten eller starten av kolonnelisten – og for å unngå en IndexError, tilbakestiller vi indeksen til motsatt verdi og simulerer en syklus. Går under 0 vil få oss tilbake til slutt av kolonnelisten, og å gå over den siste kolonnen vil gå tilbake til den første.

Etter å ha funnet ut hvor vi befinner oss – vi rydde Axes, siden vi skulle plotte igjen på toppen av en eksisterende tomt uten å fjerne den via cla() (cløret axes). Du kan alternativt hope opp funksjonsrelasjoner også, ved å plotte oppå hverandre og bruke cla() uttalelse når du tilbakestiller indeksen ved slutten/starten av syklusen.

Etter å ha ryddet Axes – Vi har et ryddet lerret å male på med ax.scatter() funksjon. I dette eksemplet er den faste funksjonen Alkohol, så den er tilstede til enhver tid. Den andre funksjonen varierer, og kan nås via iloc[], passerer inn indeksen til kolonnen. Dette returnerer en Series som vi kan bruke i dette plottet. På samme måte kan vi få tilgang kolonnenavn gjennom deres indeks også - df.columns[index], som brukes til å angi Y-akseetiketten.

Til slutt øker/minsker vi telleren og ringer plt.draw() å oppdatere Figure:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Når vi klikker på Neste funksjon knappen, vil neste funksjon i listen over kolonner bli plottet mot Alkohol, og Figure vil bli riktig oppdatert – etikettene, markørene og skalaen. Det samme gjelder omvendt – Forrige funksjon vil krysse listen i motsatt retning, slik at vi kan sykle frem og tilbake, med en sikkerhetsmekanisme som nullstiller telleren hver gang vi kommer til slutten eller begynnelsen av syklusen.

Legge til radioknapper og avmerkingsbokser

Radio knapper brukes til å la en bruker velge én verdi ut av flere verdier. Bare én alternativknapp kan velges om gangen, og de representerer vanligvis et valg. Merk av i boksene kan brukes hvis du vil la brukeren velge flere alternativer samtidig.

OBS: Det er svært begrenset mulighet til å sjekke om en avkrysningsboks er on or off. Faktisk er det ingen ut av boksen. Du kan bare sjekke om boksen er det presset or ikke, som utgjør en alvorlig begrensning for hvordan det kan brukes siden vi ikke aner i hvilken tilstand det var før det. Det eneste alternativet er å holde din egen teller/sjekke den nåværende tilstanden til boksen med en boolsk, og endre logikken basert på det.

Dette vil tillate deg for eksempel å legge til en avmerkingsboks for hver tilpasningsargument av et bestemt plot, slik at brukeren kan angi dem True or False (avmerket eller uavmerket), eller annen ikke-motstridende kartlegging basert på disse tilstandene.

Men siden API-en er begrenset i seg selv, vil vi begrense oss til den tiltenkte bruken også - slå ting av og på. Vi har to funksjoner som vi kan snu on og off via en avmerkingsboks. Merk at selv denne funksjonaliteten er begrenset til objekter som du kan sjekke om de er synlige eller ikke.

På den annen side ønsker vi ikke å la brukeren bruke to skalaer samtidig, eller sette to X-grenser samtidig, siden bare setningen som kalles andre i sekvensen vil bli brukt. For disse – vi bruker radioknapper.

La oss legge til et par radioknapper for å la brukeren velge akseområdet via et par radioknapper, men også la dem slå funksjonsvisualiseringer on og 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()

Igjen, vi har to metoder i EventHandler() klasse – set_range() og apply_features(). De set_range() metoden setter området til enten "liten" eller "stor", ved å justere AxesX- og Y-grenser. De apply_features() funksjonen endrer visible felt av linjeplottene vi laget tidligere, basert på deres nåværende visible status. Hvis visible == True, slår vi av Line Plot, og omvendt.

Vi må stole på den innebygde muligheten til å sjekke synligheten til linjeplotter, siden vi ikke kan sjekke om avmerkingsboksen var merket av eller ikke før. Den samme evnen kan etterlignes med en status boolsk i omfanget av EventHandler() klasse, som er satt til True og False ved hvert klikk, for plottyper som ikke støtter å sjekke om de er synlige ut av boksen.

Å kjøre denne koden resulterer i en Figure med to sett med knapper nederst. Hvis vi krysser av i begge avmerkingsboksene, vil begge linjeplottene vises:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Vi kan slå dem av individuelt:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Og vi kan endre rekkevidden til Axes via radioknappene:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Legge til tekstbokser

Tekstbokser Er vant til samle data fra brukeren – og vi kan endre plottene basert på disse dataene. For eksempel kan vi be en bruker om å skrive inn navnet på en funksjon, eller sette inn en funksjon som plottet vårt skal visualisere. Det kan selvfølgelig være vanskelig å jobbe med brukerinndata – det er alltid kantsaker å se etter.

La oss skrive et skript som lar brukeren legge inn en funksjonsnavn av et datasett, og Axes oppdateringer på hver innsending for å gjenspeile innspillene. For brukerens bekvemmelighet gir vi dem beskjed hvis inndataene ikke kunne matches med et kolonnenavn:

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

Vi har en enkel sjekk for å se om det er gitt feature_name er blank eller None, i så fall gjør vi ingenting. Hvis ikke, sjekker vi om feature_name er til stede i DataFrame, ved å legge ved en melding om at funksjonen ikke ble funnet hvis den ikke er til stede. Før vi legger ved teksten, må vi imidlertid sørge for at den forrige meldingen er fjernet, slik at den nye ikke overlapper den. De axes.texts eiendom er en liste over alle Text forekomster på en Axes. Siden Axes har allerede en Text for eksempel som tilhører vår TextBox, vi ønsker ikke å fjerne noe hvis det er 2 eller færre Text forekomster til stede – feilmeldingen og TextBox merkelapp.

Hvis over to, har vi allerede fått en feilmelding, som bør fjernes.

Hvis funksjonen is til stede i DataFrameskjønt, vi fjerner Axes og plott det:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Legger til spanvelgere

Spennselger kan brukes til å la brukeren velge et dataspenn og fokusere på det, og sette aksegrensene basert på det valget. Som standard støtter mange biblioteker denne funksjonaliteten, selv om Matplotlib dessverre ikke gjør det, og vi må gjøre dette manuelt. I tillegg må vi legge til en ekstra "Nullstille" knappen hvis vi vil Zoome ut også.

For å legge til en Span Selector, trenger vi ikke dedikere en helt ny Axes for den – vi kan feste den til en eksisterende, noe som gir mye mening. Når du genererer en SpanSelector, leverer vi Axes den tilhører, så vel som hendelsesbehandleren, etterfulgt av 'horizontal' or 'vertical', som roterer Axes og Span Selector begge.

De useblit argument er vanligvis satt til True fordi det forbedrer ytelsen på de fleste backends. I tillegg har vi lagt til noen få stylingegenskaper, for eksempel innstilling av alpha av rektangelet opprettet som en spennvelger til 0.5 og facecolor til en fin 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()

Å kjøre dette genererer et plott der vi kan velge spenn og zoome inn på dem ved å sette aksegrensene til de angitte verdiene:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Legge til glidebrytere

Sliders tillate brukere å velge mellom mange verdier intuitivt ved å skyve en markør og velge en verdi. Vanligvis brukes glidebrytere til kontinuerlig å oppdatere en verdi på et plott, for eksempel området or til og med en funksjon. For eksempel kan du justere verdien til en konstant gjennom en glidebryter, som igjen påvirker en funksjon som er avhengig av den konstanten.

La oss skrive et skript som lar oss endre Y- og X-aksegrensene, gjennom en glidebryter, som lar oss endre perspektivet vi ser dataene våre fra:

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

Vi har justert polstringen for å tillate en glidebryter på venstre og bunn av Axes, og plottet et enkelt linjeplott. Å legge til en glidebryter krever at vi lager en Axes for det, som med de fleste andre widgets, og tilordne det til ax argument av Slider gjennom konstruktøren. I tillegg kan vi angi minimums-, maksimums- og startverdiene for glidebryteren. Disse vil vanligvis være dynamiske områder, basert på dataene du plotter, men kan også angis manuelt skalarverdier.

Endelig, Sliders kan orienteres horisontalt eller vertikalt. Siden de er ment å oppdateres kontinuerlig via et muse-sveip – den on_changed() funksjonen brukes til å utløse et svar når en bruker gir innspill. Vi har finjustert EventHandler klasse med en update() funksjon som ganske enkelt justerer verdiene til X- og Y-grensene basert på value av de respektive glidebryterne.

Å kjøre denne koden vil produsere et plott med to glidebrytere, som vi kan bruke til å endre omfanget av Axes:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Tidstempel:

Mer fra Stackabuse