Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Matplotlib-widgets

Matplotlib er ikke kun til statiske plots. Mens GUI'er typisk oprettes med GUI-biblioteker og rammer som f.eks PyQt, Tkinter, Desperat , wxPython, og mens Python har fremragende integration med PyQt, Tkinter , wxPython – der er ingen grund til at bruge nogen af ​​disse til nogle grundlæggende GUI-funktioner, gennem Matplotlib-widgets.

matplotlib.widgets modulet har flere klasser, herunder AxesWidget, hvoraf Buttons, CheckButtons, Sliders, TextBoxes osv. er afledt. Disse accepterer alle Axes de bliver tilføjet som det eneste obligatoriske konstruktorargument, og deres positionering skal indstilles manuelt. En ting at bemærke er, at widget er akserne, så du vil oprette en Axes forekomst for hver widget.

En anden ting at bemærke er, at du skal beholde referencer til widgets ellers kan de blive indsamlet affald.

Hver af dem kan også deaktiveres ved indstilling active til False, i så fald vil de ikke reagere på nogen begivenheder, såsom at blive klikket på. Når det er sagt, kan vi introducere en ny type interaktivitet til vores plots gennem forskellige GUI-elementer og komponenter.

Bemærk: Matplotlib er ikke beregnet til at blive brugt til højkvalitets GUI-oprettelse eller brugervenlige systemer. Disse widgets er rudimentære, ser ikke rigtig godt ud og har begrænset funktionalitet. De er ment som en måde at prototype og teste ting på i stedet for rent faktisk at sende dem.

Hvis du har arbejdet med PyQt før – vil du måske bemærke, at den generelle syntaks og tilgang til tilføjelse af disse widgets, såvel som at forbinde dem til hændelseshandlere, er ret velkendt.

Tilføjelse af knapper

Lad os starte med knapper - det matplotlib.widgets modul definerer en Button klasse. For at forbinde til det, kalder vi on_clicked() funktion, som udfører den funktion, vi leverer. Når et klik er blevet registreret, udføres funktionen.

Mens vi opretter knappen, tildeler vi en Axes til den, bruges til positionering. Vi kan også bestå i en label på det tidspunkt for at tilføje noget tekst og kommentere det for en bruger. Det color , hovercolor argumenter definerer farven på knappen før og efter, den holdes over.

Da vi tager os af placeringen og pladsen til alle widgets – lad os skabe en Figure , Axes, tillad lidt mellemrum i bunden for at tilføje en knap, og plot et tomt scatter-plot. Så vil vi definere en EventHandler klasse, der har en enkelt metode add_random(). Metoden genererer to tilfældige tal og plotter en markør for dem på Axes vi har lavet før og kalder plt.draw(), som gentegner Figure. Ved opdatering af grunde skal vi altid ringe plt.draw() igen for faktisk at opdatere det:

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 inde i den og en knap i øverste højre hjørne af skærmen, i sin egen Axes:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Og efter at have trykket på knappen et par dusin gange, er vores ax vil blive udfyldt med tilfældige markører:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Mere praktisk kunne vi skabe en cyklus af funktioner for at blive plottet ved hvert knaptryk. Dette kræver et par justeringer af EventHandler, samt en anden knap for at gå tilbage gennem den cyklus.

Lad os bruge Rødvin kvalitet datasættet igen, og visualiser flere funktioner i forhold til Procenter funktion. Da vi ikke kan være generet af at plotte disse individuelt ved at skrive koden for at plotte den ene funktion mod den anden, og derefter ændre den kode til at plotte en anden funktion mod den anden.

Oprettelse af en Scatter Matrix kan måske hjælpe os her, men hvis datasættet har mange funktioner, vil det være ret ulæseligt, og vi kommer ikke langt. Hvis du gerne vil have både store plots, som du nemt kan se og fortolke, såvel som at have flere funktioner, der går igennem uden nogen ekstra indsats – du kan automatisere denne proces 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()

EventHandler klasse har nu to metoder – next_feature() , previous_feature(). Begge disse kontrollere, om tælleren i har nået slutningen eller starten af ​​kolonnelisten – og for at undgå en IndexError, nulstiller vi indekset til den modsatte værdi og simulerer en cyklus. Går nedenunder 0 vil få os tilbage til ende af kolonnelisten, og at gå over den sidste kolonne vil vende tilbage til den første.

Efter at have konstateret, hvor vi befinder os – vi rydde Axes, da vi ville plotte igen oven på et eksisterende plot uden at rydde det via cla() (cløre axes). Du kan alternativt også ophobe egenskabsrelationer ved at plotte oven på hinanden og bruge cla() sætning ved nulstilling af indekset ved slutningen/starten af ​​cyklussen.

Efter at have ryddet Axes – vi har fået et ryddet lærred at male på med ax.scatter() fungere. I dette eksempel er den faste funktion Procenter, så den er til stede hele tiden. Den anden funktion varierer og kan tilgås via iloc[], passerer i indekset for kolonnen. Dette returnerer en Series som vi kan bruge i dette plot. På samme måde kan vi få adgang kolonnenavne også gennem deres indeks – df.columns[index], som bruges til at indstille Y-akse-etiketten.

Til sidst øger/mindsker vi tælleren og ringer plt.draw() at opdatere Figure:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Når vi klikker på Næste funktion knappen, vil den næste funktion i listen over kolonner blive plottet mod Procenter, og Figure vil blive passende opdateret – etiketterne, markørerne og skalaen. Det samme gælder den anden vej rundt – Forrige funktion vil krydse listen i den modsatte retning, hvilket giver os mulighed for at cykle frem og tilbage med en sikkerhedsmekanisme, der nulstiller vores tæller, hver gang vi kommer til slutningen eller begyndelsen af ​​cyklussen.

Tilføjelse af radioknapper og afkrydsningsfelter

Radio knapper bruges til at give en bruger mulighed for at vælge én værdi ud af flere værdier. Der kan kun vælges én alternativknap ad gangen, og de repræsenterer typisk et valg. Afkrydsningsfelter kan bruges, hvis du gerne vil lade brugeren vælge flere muligheder på én gang.

Bemærk: Der er meget begrænset mulighed for at kontrollere, om et afkrydsningsfelt er on or off. Faktisk er der ingen ud af boksen. Du kan kun nogensinde kontrollere, om boksen er presset or ikke, hvilket udgør en alvorlig begrænsning for, hvordan det kan bruges, da vi ikke aner, i hvilken tilstand det var før det. Det eneste alternativ er at holde din egen tæller/tjekke den aktuelle tilstand af boksen med en boolean og ændre logikken baseret på det.

Dette vil give dig mulighed for for eksempel at tilføje et afkrydsningsfelt for hver tilpasningsargument af et bestemt plot, så brugeren kan indstille dem True or False (markeret eller umarkeret), eller enhver anden ikke-modstridende kortlægning baseret på disse tilstande.

Men da API'en er begrænset i sig selv, vil vi også begrænse os til den tilsigtede brug - ved at tænde og slukke for tingene. Vi har to funktioner, som vi kan vende on , off via et afkrydsningsfelt. Bemærk, at selv denne funktionalitet er begrænset til objekter, for hvilke du kan kontrollere, om de er synlige eller ej.

På den anden side ønsker vi ikke at tillade brugeren at anvende to skalaer på én gang, eller at sætte to X-grænser på én gang, da kun sætningen kaldet anden i sekvensen ville blive anvendt. Til disse – ville vi bruge radioknapper.

Lad os tilføje et par radioknapper for at lade brugeren vælge akseområdet via et par radioknapper, men også tillade dem at dreje funktionsvisualiseringer on , 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()

Igen har vi to metoder i EventHandler() klasse – set_range() , apply_features(). Det set_range() metode indstiller området til enten "lille" eller "stort", ved at justere Axes' X- og Y-grænser. Det apply_features() funktion ændrer visible felt af de linjeplot, vi lavede tidligere, baseret på deres nuværende visible status. Hvis visible == True, slår vi Line Plottet fra og omvendt.

Vi er nødt til at stole på den indbyggede mulighed for at kontrollere synligheden af ​​Line Plots, da vi ikke kan kontrollere, om afkrydsningsfeltet var markeret eller ej før. Den samme evne kan efterlignes med en status boolesk i omfanget af EventHandler() klasse, som er sat til True , False ved hvert klik for plottyper, der ikke understøtter kontrol af, om de er synlige ud af boksen.

Kørsel af denne kode resulterer i en Figure med to sæt knapper i bunden. Hvis vi markerer begge afkrydsningsfelter, vises begge linjeplot:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Vi kan slå dem fra individuelt:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Og vi kan ændre rækkevidden af Axes via radioknapperne:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Tilføjelse af tekstbokse

Tekstbokse er vant til indsamler data fra brugeren – og vi kan ændre plottene ud fra disse data. For eksempel kan vi bede en bruger om at indtaste navnet på en funktion eller om at indsætte en funktion, som vores plot kan visualisere. Det kan selvfølgelig være vanskeligt at arbejde med brugerinput – der er altid kantsager, man skal være opmærksom på.

Lad os skrive et script, der giver brugeren mulighed for at indtaste en funktionsnavn af et datasæt, og Axes opdateringer på hver indsendelse for at afspejle input. Af hensyn til brugerens bekvemmelighed giver vi dem besked, hvis inputtet 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 simpel kontrol for at se, om den medfølgende feature_name er blank eller None, i så fald gør vi ikke noget. Hvis ikke, tjekker vi, om feature_name er til stede i DataFrame, vedhæfter en besked om, at funktionen ikke blev fundet, hvis den ikke er til stede. Før vi vedhæfter teksten, skal vi dog sikre os, at den tidligere besked er fjernet, så den nye ikke overlapper med den. Det axes.texts ejendom er en liste over alle Text instanser på en Axes. Siden Axes har allerede en Text for eksempel, der tilhører vores TextBox, vi ønsker ikke at fjerne noget, hvis der er 2 eller færre Text tilstedeværende tilfælde – fejlmeddelelsen og TextBox etiket.

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

Hvis funktionen is til stede i DataFrame, dog rydder vi Axes og plot det:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Tilføjelse af spændviddevælgere

Spændviddevælgere kan bruges til at give brugeren mulighed for at vælge et dataområde og fokusere på det ved at indstille aksegrænserne baseret på dette valg. Som standard understøtter mange biblioteker denne funktionalitet, selvom Matplotlib desværre ikke gør det, og vi bliver nødt til at gøre dette manuelt. Derudover bliver vi nødt til at tilføje en ekstra "Nulstil" knappen, hvis vi vil zoome ud også.

For at tilføje en Spændviddevælger, behøver vi ikke dedikere en helt ny Axes for den – vi kan knytte den til en eksisterende, hvilket giver rigtig god mening. Ved generering af en SpanSelector, vi leverer Axes den tilhører, såvel som hændelseshandleren, efterfulgt af 'horizontal' or 'vertical', som roterer Axes , Span Selector begge.

useblit argument er typisk sat til True fordi det forbedrer ydeevnen på de fleste backends. Derudover har vi tilføjet et par stylingegenskaber, såsom indstilling af alpha af rektangelet oprettet som en spændviddevælger til 0.5 og facecolor til en dejlig 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()

Ved at køre dette genereres et plot, hvorpå vi kan vælge spændvidder og zoome ind på dem ved at indstille aksegrænserne til de angivne værdier:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Tilføjelse af skydere

Sliders tillade brugere at vælge mellem mange værdier intuitivt ved at skubbe en markør og vælge en værdi. Typisk bruges skydere til løbende at opdatere en værdi på et plot, såsom dets rækkevidde or endda en funktion. For eksempel kan du justere værdien af ​​en konstant gennem en skyder, som igen påvirker en funktion, der er afhængig af denne konstant.

Lad os skrive et script, der giver os mulighed for at ændre Y- og X-aksegrænserne gennem en skyder, som vil lade os ændre perspektivet, hvorfra vi ser vores 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()

Vi har justeret polstringen for at tillade en skyder på venstre og nederste del af Axes, og plottede et simpelt linjeplot. Tilføjelse af en skyder kræver, at vi laver en Axes for det, ligesom med de fleste andre widgets, og tildel det til ax argument af Slider gennem konstruktøren. Derudover kan vi indstille minimum-, maksimum- og startværdierne for skyderen. Disse vil typisk være dynamiske områder baseret på de data, du plotter, men kan også indstilles manuelt.

Endelig Sliders kan orienteres vandret eller lodret. Da de er beregnet til løbende at blive opdateret via et muse-swipe - det on_changed() funktion bruges til at udløse et svar, når en bruger giver input. Vi har justeret EventHandler klasse med en update() funktion, der blot justerer værdierne for X- og Y-grænserne baseret på valbrugen af ​​de respektive skydere.

At køre denne kode vil producere et plot med to skydere, som vi kan bruge til at ændre omfanget af Axes:

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Matplotlib Widgets PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Tidsstempel:

Mere fra Stablemisbrug