Matplotlib isn’t only for static plots. While GUIs are typically created with GUI libraries and frameworks such as PyQt, Tkinter, Kétségbeesett és a wxPython, és bár a Python kiválóan integrálja a PyQt-t, a Tkintert és a wxPython – there’s no need to use any of these for some basic GUI functionality, through Matplotlib widgetek.
A matplotlib.widgets
modulnak több osztálya van, köztük a AxesWidget
, melyek közül Button
s, CheckButton
s, Slider
s, TextBox
es stb. származnak. Ezek mind elfogadják a 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 a tengelyek, so you’ll create an Axes
példány minden widgethez.
Egy másik dolog, amit meg kell jegyezni, az meg kell őriznie a widgetekre vonatkozó hivatkozásokat különben összegyűjtik a szemetet.
Mindegyik beállítással letiltható active
nak nek 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.
Jegyzet: 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.
Gombok hozzáadása
Kezdjük azzal gombok - A matplotlib.widgets
modul meghatározza a Button
osztály. A csatlakozáshoz hívjuk a on_clicked()
függvény, amely végrehajtja az általunk megadott függvényt. Amint egy kattintást észlel, a funkció végrehajtódik.
A gomb létrehozása közben hozzárendelünk egy Axes
hozzá, pozicionáláshoz használják. Be is léphetünk a label
abban az időben, hogy hozzáadjon egy kis szöveget és megjegyzéseket fűzzen hozzá a felhasználó számára. A color
és a 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
és a Axes
, allow for some spacing at the bottom to add a button, and plot an empty Scatter Plot. Then, we’ll define an EventHandler
osztály, amelynek egyetlen metódusa van add_random()
. A metódus két véletlen számot generál, és ezekhez jelölőt ábrázol a Axes
we’ve created before and calls plt.draw()
, amely újra megrajzolja a Figure
. When updating plots, we’ll always have to call plt.draw()
még egyszer, hogy valóban frissítse:
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()
Ennek eredményeként a Figure
, egy üres Axes
belül, és egy gomb a képernyő jobb felső sarkában, a sajátjában Axes
:
És miután néhány tucatszor megnyomtuk a gombot, a mi ax
véletlenszerű markerekkel lesz feltöltve:
Gyakorlatiasabban fogalmazva létrehozhatnánk a ciklus funkciókat, amelyek minden gombnyomásra megjelennek. Ez néhány módosítást igényel a EventHandler
, valamint egy másik gomb a cikluson való visszalépéshez.
Használjuk a Vörösbor minőség adatkészletet újra, és vizualizáljon több funkciót a 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 mindkét nagyméretű cselekmények, amelyeket könnyen megtekinthet és értelmezhet, is 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()
A EventHandler
class now has two methods – next_feature()
és a previous_feature()
. Mindkettő ellenőrzi, hogy a számláló i
has reached the end or start of the column list – and to avoid an IndexError
, visszaállítjuk az indexet az ellenkező értékre, és szimuláljuk a ciklus. Lefelé haladva 0
visszavezet minket a végén az oszloplistából, és az utolsó oszlop fölé lépve visszatérünk az elsőhöz.
After ascertaining where we’re located – we törölje a Axes
, since we’d be plotting again on top of an existing plot without clearing it via cla()
(clfül axes). Alternatív megoldásként a jellemzőkapcsolatokat is felhalmozhatja úgy, hogy egymásra ábrázolja és használja a cla()
utasítást az index alaphelyzetbe állításakor a ciklus végén/elején.
Miután törölte a Axes
– we’ve got a cleared canvas to paint on with the ax.scatter()
funkció. Ebben a példában a rögzített szolgáltatás az Alkohol, so it’s present at all times. The other feature varies, and can be accessed through iloc[]
, áthaladva az oszlop indexében. Ez visszaadja a Series
amit felhasználhatunk ebben a cselekményben. Hasonlóképpen hozzáférhetünk oszlopnevek through their index as well – df.columns[index]
, amely az Y tengely címkéjének beállítására szolgál.
Végül növeljük/csökkentjük a számlálót és hívjuk plt.draw()
hogy frissítse a Figure
:
Miután rákattintunk a Következő funkció gombot, az oszlopok listájának következő jellemzője lesz ábrázolva Alkohol, És a Figure
will be appropriately updated – the labels, markers and scale. The same goes the other way around – Előző funkció ellentétes irányban halad át a listán, lehetővé téve az oda-vissza biciklizést egy biztonsági mechanizmussal, amely minden alkalommal alaphelyzetbe állítja a számlálót, amikor a ciklus végére vagy elejére érünk.
Rádiógombok és jelölőnégyzetek hozzáadása
Rádió gombok arra szolgálnak, hogy a felhasználó kiválaszthassa egy érték kívül több értéket. Egyszerre csak egy választógomb választható ki, és ezek általában egy választást jelentenek. Jelölőnégyzetek can be used if you’d like to let the user select multiple options at once.
Jegyzet: Nagyon korlátozott a lehetőség annak ellenőrzésére, hogy a jelölőnégyzet be van-e kapcsolva on or kedvezmény. In fact, there’s none out of the box. You can only ever check if the box is sajtolt or nem, ami komoly korlátot szab a használatának, hiszen fogalmunk sincs, hogy ez előtt milyen állapotban volt. Az egyetlen alternatíva, hogy megtartja a saját számlálóját/ellenőrzését a doboz aktuális állapotára vonatkozóan egy logikai értékkel, és ennek alapján módosítja a logikát.
Ez lehetővé tenné például, hogy mindegyikhez jelölőnégyzetet adjon testreszabási argumentum egy bizonyos telek, lehetővé téve a felhasználó számára, hogy beállítsa azokat True
or False
(bejelölve vagy nem bejelölve), vagy bármilyen más, nem ütköző leképezés ezeken az állapotokon alapul.
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 és a kedvezmény 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 és a kedvezmény:
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()
osztály - set_range()
és a apply_features()
Az set_range()
method sets the range to either “small” or “large”, by adjusting the Axes
‘ X and Y-limits. The apply_features()
funkció megváltoztatja a visible
A korábban elkészített Vonalrajzok mezője aktuális állapotuk alapján visible
állapot. Ha visible == True
, kikapcsoljuk a Vonalrajzot, és fordítva.
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
logikai értékét a EventHandler()
osztályba van beállítva True
és a False
on every click, for plot types that don’t support checking if they’re visible out of the box.
Ennek a kódnak a futtatása a Figure
alján két gombkészlettel. Ha mindkét jelölőnégyzetet bejelöljük, mindkét vonalrajz megjelenik:
Egyenként is kikapcsolhatjuk őket:
És megváltoztathatjuk a tartományt Axes
a rádiógombokon keresztül:
Szövegdobozok hozzáadása
Szövegdobozok arra használják, hogy gyűjt 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 jellemző neve egy adatkészletből, és a 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()
Van egy egyszerű ellenőrzésünk, hogy megnézzük, hogy biztosított-e feature_name
üres vagy None
, in which case, we don’t do anything. If not, we check if the feature_name
jelen van a 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
tulajdonság listája az összes Text
példányok egy Axes
. Óta Axes
már rendelkezik a Text
például a miénk TextBox
, we don’t want to remove anything if there are 2 or less Text
instances present – the error message and the TextBox
címke.
If above two, we’ve already got an error message, which should be removed.
Ha a funkció is jelen van a DataFrame
, mégis töröljük a Axes
és ábrázolja:
Span Selectorok hozzáadása
Span Selectors 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 "Visszaállítás" gombot, ha akarjuk kicsinyítéshez is.
Hozzáadni a Span Selector, 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
, szállítjuk a Axes
tartozik, valamint az eseménykezelő, majd ezt követi 'horizontal'
or 'vertical'
, amely forgatja a Axes
és a Span Selector mindkettő.
A useblit
argumentum általában a következőre van állítva True
because it enhances performance on most backends. Additionally, we’ve added a few styling properties, such as setting the alpha
a téglalap kiterjedésválasztójaként létrehozott téglalapból 0.5
és a facecolor
egy szépre 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()
Ennek futtatása egy diagramot generál, amelyen a tengelyhatárok megadott értékekre állításával kijelölhetjük a fesztávokat és ráközelíthetünk:
Csúszkák hozzáadása
Sliders lehetővé teszi a felhasználók számára, hogy intuitív módon válogassanak számos érték között a marker elcsúsztatásával és egy érték kiválasztásával. Általában a csúszkákat arra használják, hogy folyamatosan frissítsenek bizonyos értékeket a diagramon, például annak tartományát or akár egy tulajdonság. Például beállíthatja egy konstans értékét egy csúszkával, ami viszont hatással van az arra a konstansra támaszkodó függvényre.
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
, és felrajzolt egy egyszerű vonalrajzot. A csúszka hozzáadásához el kell készítenünk egy Axes
hozzá, mint a legtöbb egyéb widgethez, és rendelje hozzá a ax
érve a 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.
Végül, Slider
s 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
osztály egy update()
függvény, amely egyszerűen beállítja az X és Y határértékek értékét a val
a megfelelő csúszkák használatával.
Ennek a kódnak a futtatása két csúszkával egy plot-ot fog készíteni, amelyek segítségével megváltoztathatjuk a hatókörét Axes
:
- hozzáférés
- Minden termék
- lehetővé téve
- már
- Másik
- api
- megközelítés
- érvek
- körül
- Kezdet
- hogy
- Doboz
- beépített
- hívás
- ami
- esetek
- változik
- ellenőrzése
- kód
- Oszlop
- tudott
- Pár
- létrehozása
- Jelenlegi
- Jelenlegi állapot
- dátum
- elszánt
- észlelt
- tucat
- dinamikus
- könnyen
- él
- esemény
- események
- példa
- kiváló
- Funkció
- Jellemzők
- vezetéknév
- Összpontosít
- talált
- funkció
- funkcionalitás
- általános
- megy
- nagy
- Zöld
- tekintettel
- segít
- itt
- Hogyan
- HTTPS
- ötlet
- Beleértve
- index
- integráció
- IT
- Címkék
- nagy
- Korlátozott
- vonal
- Lista
- Mátrix
- a legtöbb
- számok
- Opciók
- Más
- másképp
- teljesítmény
- perspektíva
- be
- nyomja meg a
- folyamat
- gyárt
- ingatlan
- rádió
- hatótávolság
- RE
- válasz
- Eredmények
- Visszatér
- Biztonság
- Mondott
- Skála
- Képernyő
- kiválasztott
- értelemben
- készlet
- beállítás
- Egyszerű
- kicsi
- So
- Hely
- kezdet
- Állami
- nyilatkozat
- Államok
- Állapot
- kínálat
- támogatás
- Systems
- teszt
- Keresztül
- idő
- felső
- Frissítések
- Frissítés
- us
- Felhasználók
- érték
- Megnézem
- láthatóság
- látható
- vajon
- nélkül
- dolgozott
- dolgozó
- írás
- X
- év
- gyertya