hvPlot-Beispiele¶
Installation¶
Um die Beispiele ausführen zu können, muss zusätzlich Snappy installiert werden.
Mit Spack könnt ihr Snappy in eurem Kernel bereitstellen, z.B. mit:
$ spack env activate python-311
$ spack install snappy
Alternativ könnt ihr Snappy auch mit anderen Paketmanagern installieren, z.B.
Für Debian/Ubuntu:
$ sudo apt install libsnappy-dev
Für Windows:
Snappy benötigt Microsoft Visual C++ ≥ 14.0. Dies kann installiert werden mit den Microsoft C++ Build Tools.
Für Mac OS:
$ brew install snappy
Anschließend sollten für euren Kernel noch weitere Pakete installiert werden, z.B. mit:
$ pipenv install intake intake-parquet s3fs python-snappy pyviz-comms
…
Einführung¶
Als erstes importieren wir NumPy und pandas um anschließend einen kleinen Satz zufälliger Daten zu erstellen:
[1]:
import numpy as np
import pandas as pd
index = pd.date_range("1/1/2000", periods=1000)
df = pd.DataFrame(
np.random.randn(1000, 4), index=index, columns=list("ABCD")
).cumsum()
df.head()
[1]:
A | B | C | D | |
---|---|---|---|---|
2000-01-01 | 1.431985 | 1.378913 | 0.539567 | 0.257977 |
2000-01-02 | 1.266573 | 0.834050 | 1.176750 | 1.458363 |
2000-01-03 | 1.799283 | 0.945437 | 1.792629 | -0.220764 |
2000-01-04 | 2.131248 | 0.160377 | 1.186063 | -0.702810 |
2000-01-05 | 3.574972 | 2.274926 | 1.759324 | -1.297244 |
pandas.plot ()
-API¶
pandas bietet standardmäßig Matplotlib-basiertes Plotten mit der .plot()
-Methode:
[2]:
%matplotlib inline
df.plot();
Das Ergebnis ist ein PNG-Bild, das leicht angezeigt werden kann, ansonsten aber statisch ist.
Hinweis: In pandas > 0.25.0 kann das Backend ausgetauscht werden, z.B. mit
pd.options.backend.plotting == 'holoviews',
. Weitere Informationen hierzu findet ihr unter pandas-API.
.hvplot()
¶
Wenn wir statt %matplotlib inline
zu import hvplot.pandas
und der df.hvplot
-Methode wechseln, , wird jetzt ein interaktiv erforschbares Bokeh-Diagramm erzeugt mit Verschieben und Vergrößern/Verkleinern sowie anklickbaren Legenden:
[3]:
import hvplot.pandas
df.hvplot()
[3]:
Ein solches interaktive Diagramm erleichtert das Erkunden der der Daten erheblich, ohne dass hierfür zusätzlicher Code geschrieben werden müsste.
Native hvPlot
-API¶
Für das obige Diagramm hat hvPlot die pandas-.hvplot()
-Methode dynamisch hinzugefügt, sodass ihr dieselbe Syntax wie bei pandas-Plots verwenden könnt. Wenn ihr ein expliziteres Vorgehen bevorzugt, könnt ihr stattdessen direkt mit den hvPlot-Objekten arbeiten:
[4]:
import holoviews as hv
from hvplot import hvPlot
hv.extension("bokeh")
plot = hvPlot(df)
plot(y=["A", "B", "C", "D"])
[4]:
Hilfe¶
Wenn ihr in IPython oder Jupyter-Notebooks arbeitet, vervollständigen die hvplot
-Methoden automatisch gültige Schlüsselwörter. Wenn ihr beispielsweise nach dem Deklarieren des Plottyps die Tabulatortaste drücken, werden alle gültigen Schlüsselwörter und die Dokumentzeichenfolge angezeigt:
df.hvplot.line(TAB
Außerhalb einer interaktiven Umgebung werden mit hvplot.help
alle Informationen für einen Diagrammtyp angezeigt, z.B.:
[ ]:
hvplot.help("line")
Siehe auch:
Weitere Informationen zu den verfügbaren Optionen erhaltet ihr in Customization.
Plotting¶
In den folgenden Beispielen wird neben der pandas- auch die dask-hvPlot-API verwendet:
[6]:
import hvplot.dask
Das hvplot.sample_data
-Modul erstellt diese Datensätze als Intake-Datenkataloge, die wir mit pandas laden können:
[7]:
from hvplot.sample_data import airline_flights, us_crime
crime = us_crime.read()
print(type(crime))
crime.head()
<class 'pandas.core.frame.DataFrame'>
[7]:
Year | Population | Violent crime total | Murder and nonnegligent Manslaughter | Legacy rape /1 | Revised rape /2 | Robbery | Aggravated assault | Property crime total | Burglary | ... | Violent Crime rate | Murder and nonnegligent manslaughter rate | Legacy rape rate /1 | Revised rape rate /2 | Robbery rate | Aggravated assault rate | Property crime rate | Burglary rate | Larceny-theft rate | Motor vehicle theft rate | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1960 | 179323175 | 288460 | 9110 | 17190 | NaN | 107840 | 154320 | 3095700 | 912100 | ... | 160.9 | 5.1 | 9.6 | NaN | 60.1 | 86.1 | 1726.3 | 508.6 | 1034.7 | 183.0 |
1 | 1961 | 182992000 | 289390 | 8740 | 17220 | NaN | 106670 | 156760 | 3198600 | 949600 | ... | 158.1 | 4.8 | 9.4 | NaN | 58.3 | 85.7 | 1747.9 | 518.9 | 1045.4 | 183.6 |
2 | 1962 | 185771000 | 301510 | 8530 | 17550 | NaN | 110860 | 164570 | 3450700 | 994300 | ... | 162.3 | 4.6 | 9.4 | NaN | 59.7 | 88.6 | 1857.5 | 535.2 | 1124.8 | 197.4 |
3 | 1963 | 188483000 | 316970 | 8640 | 17650 | NaN | 116470 | 174210 | 3792500 | 1086400 | ... | 168.2 | 4.6 | 9.4 | NaN | 61.8 | 92.4 | 2012.1 | 576.4 | 1219.1 | 216.6 |
4 | 1964 | 191141000 | 364220 | 9360 | 21420 | NaN | 130390 | 203050 | 4200400 | 1213200 | ... | 190.6 | 4.9 | 11.2 | NaN | 68.2 | 106.2 | 2197.5 | 634.7 | 1315.5 | 247.4 |
5 rows × 22 columns
Alternativ können wir dask.DataFrame
verwenden:
[8]:
flights = airline_flights.to_dask().persist()
print(type(flights))
flights.head()
<class 'dask.dataframe.core.DataFrame'>
[8]:
year | month | day | dayofweek | dep_time | crs_dep_time | arr_time | crs_arr_time | carrier | flight_num | ... | taxi_in | taxi_out | cancelled | cancellation_code | diverted | carrier_delay | weather_delay | nas_delay | security_delay | late_aircraft_delay | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2008.0 | 11.0 | 15.0 | 6.0 | 1411.0 | 1420.0 | 1535.0 | 1546.0 | b'OO' | 4391.0 | ... | 5.0 | 11.0 | 0.0 | None | 0.0 | NaN | NaN | NaN | NaN | NaN |
1 | 2008.0 | 11.0 | 28.0 | 5.0 | 1222.0 | 1230.0 | 1345.0 | 1356.0 | b'OO' | 4391.0 | ... | 5.0 | 15.0 | 0.0 | None | 0.0 | NaN | NaN | NaN | NaN | NaN |
2 | 2008.0 | 11.0 | 22.0 | 6.0 | 1414.0 | 1420.0 | 1540.0 | 1546.0 | b'OO' | 4391.0 | ... | 5.0 | 10.0 | 0.0 | None | 0.0 | NaN | NaN | NaN | NaN | NaN |
3 | 2008.0 | 11.0 | 15.0 | 6.0 | 1304.0 | 1305.0 | 1507.0 | 1519.0 | b'OO' | 4392.0 | ... | 10.0 | 9.0 | 0.0 | None | 0.0 | NaN | NaN | NaN | NaN | NaN |
4 | 2008.0 | 11.0 | 22.0 | 6.0 | 1323.0 | 1305.0 | 1536.0 | 1519.0 | b'OO' | 4392.0 | ... | 5.0 | 21.0 | 0.0 | None | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17.0 |
5 rows × 29 columns
Die Plot-API¶
Die Schnittstellen
dask.dataframe.DataFrame.hvplot
pandas.DataFrame.hvplot
intake.DataSource.plot
und ihre Series
-Äquivalente bieten eine leistungsfähige High-Level-API um auch komplexe Plots erzeugen zu können. Dabei kann die .hvplot
-API entweder direkt oder als Namespace verwendet werden, um bestimmte Plottypen zu generieren.
Die expliziteste Methode zur Verwendung der Plot-API besteht darin, die Namen der Spalten anzugeben, die auf der x- bzw. y-Achse geplottet werden sollen:
[9]:
crime.hvplot.line(x="Year", y="Violent Crime rate")
[9]:
Zusätzlich kann auch noch der Diagrammtyp mit kind
angegeben werden:
[10]:
crime.hvplot(x="Year", y="Violent Crime rate", kind="scatter")
[10]:
Mit der by
-Variable könnt ihr die Daten in einer oder mehreren zusätzlichen Spalten gruppieren. Als Beispiel wird im Folgenden die Abfahrtsverzögerung ("depdelay"
) als Funktion der "distance"
dargestellt und die Daten nach "carrier"
gruppiert:
[11]:
flight_subset = flights[flights.carrier.isin([b"OH", b"F9"])]
flight_subset.hvplot(
x="distance",
y="depdelay",
by="carrier",
kind="scatter",
alpha=0.2,
persist=True,
)
[11]: