Commit 1b40a41a authored by Jochen Schulz's avatar Jochen Schulz
Browse files

small changes

parent e2e998da
Pipeline #222917 failed with stage
in 10 minutes and 25 seconds
......@@ -298,7 +298,7 @@ und mit HoloMap können wir uns alle eindeutigen Monate (12) ansehen und durchge
```{code-cell} ipython3
plots = {k:hv.HeatMap(temperatureframe.loc[k], kdims=['longitude', 'latitude'], vdims = ['tem']) for k in temperatureframe.index.unique()}
hv.HoloMap(plots).options(height=400,width=700)
hv.HoloMap(plots).options(height=400,width=600)
```
<!--
......
......@@ -46,6 +46,7 @@ hv.Curve((h, err), 'h', 'err').options(logx=True, logy=True, show_grid=True, xti
# Ungenauigkeit
```
## Aufgabe 2
(Genauigkeit beim Darstellen)
......
......@@ -3,8 +3,10 @@ jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.10.3
kernelspec:
display_name: Python 3
display_name: Python 3 (ipykernel)
language: python
name: python3
---
......@@ -36,8 +38,7 @@ Wir möchten uns hier insbesondere ansehen:
* Kombination von Grafiken (nebeneinander und übereinander)
* Interaktion (z.B. Parameter abändern und neu berechnen/darstellen)
```{code-cell}
```{code-cell} ipython3
import holoviews as hv
hv.extension('bokeh')
```
......@@ -58,7 +59,7 @@ Wir nutzen ausschließlich `bokeh`, weil es mehr Interaktivität erlaubt und am
**Beispiel**
```{code-cell}
```{code-cell} ipython3
import numpy as np
```
......@@ -66,9 +67,9 @@ import numpy as np
data = np.load('data/images/mandelbrot.npy')
```
```{code-cell} ipython3
:tags: [hide-input]
```{code-cell}
:tags: ["hide-input"]
import requests
import io
......@@ -77,7 +78,7 @@ response.raise_for_status()
data = np.load(io.BytesIO(response.content))
```
```{code-cell}
```{code-cell} ipython3
options = {'Contours':dict(show_legend=False),
'Points': dict(size_index=2, size=8, color='blue')}
......@@ -105,7 +106,7 @@ Alle Optionen für holoviews können über sogenannte *magics* im jupyter notebo
Hiermit haben wir eine klare Trennung zwischen Daten, Visualisierung und den Darstellungsoptionen (siehe funktionale Programmierung).
```{code-cell}
```{code-cell} ipython3
%output size=150
```
......@@ -125,7 +126,7 @@ hv.Curve(data, kdims='x', vdims='y', **kwargs)
Diese sind entweder ein String oder Tuple von Strings, die die Namen der Werte-Dimensionen erhalten.
Sie werden in der Reihenfolge der Spalten in `data` gesetzt. Werden weitere Spalten in `data` mit übergeben, kann man sie über `vdims` dann auch benennen und über diese Namen später zugreifen.
```{code-cell}
```{code-cell} ipython3
x = np.linspace(-np.pi, np.pi, 100)
b = hv.Curve((x, np.sin(x)))
b
......@@ -133,22 +134,21 @@ b
Die Spaltennamen sieht man dann auch in der Darstellung innerhalb des holoviews-Objektes:
```{code-cell}
```{code-cell} ipython3
b.data
```
oder in den Objekt-Attributen .kdims und .vdims:
```{code-cell}
```{code-cell} ipython3
b.kdims, b.vdims
```
```{code-cell}
```{code-cell} ipython3
b = hv.Curve((x, np.sin(x)), kdims='h', vdims='k')
b.data, b.kdims, b.vdims
```
### Optionen
Neben direkten Optionen, die für die Funktionsweise der Darstellung entscheidend sind, gibt es noch *stilistische* Optionen; diese ändern nur das Aussehen
......@@ -179,7 +179,7 @@ hv.help(hv.holoviewsobject)
Die vollständige Liste für `Curve` gibt es dann mit
```{code-cell}
```{code-cell} ipython3
hv.help(hv.Curve)
```
......@@ -188,7 +188,7 @@ schreiben wir die Optionen als ein dictionary-Objekt vorab auf. Dafür muss
dann der Typ der Grafik jeweils als key angegeben werden. Als value stehen
dann dort alle kwargs wiederum als dictionary.
```{code-cell}
```{code-cell} ipython3
options = {'Curve': dict(color='blue', line_width=2, line_dash='dashed')}
#options = {'Curve': {'color':'blue', 'line_width':2, 'line_dash':'dashed'}
......@@ -205,10 +205,11 @@ hv.Curve((x, np.sin(x))).options(options)
setzt den Titel der Grafik auf *string*:
```{code-cell}
```{code-cell} ipython3
x = np.linspace(-np.pi, np.pi, 100)
hv.Curve((x, np.sin(x)), vdims="h").options(options).relabel("Sinuskurve")
```
(layouts)=
## Nebeneinander - Layouts
......@@ -230,14 +231,14 @@ Dann ist die Visualisierung von `plot1` links neben der Visualisierung von `plot
Wir können sogar Teile der Daten und damit Visualisierung aus einem Plot
auswählen mit einem *slice*.
```{code-cell}
```{code-cell} ipython3
b+b[1:4,:]
```
`hv.Layout` ist äquivalent zu dem `+` Operator, aber dadurch, dass wir dann
mehrere Zeilen benutzen können, ist es manchmal einfach übersichtlicher.
```{code-cell}
```{code-cell} ipython3
hv.Layout([
b,
b[1:4]
......@@ -246,7 +247,7 @@ hv.Layout([
Die Text-Ausgabe der addierten Grafiken zeigt das *layout* und Struktur der Daten:
```{code-cell}
```{code-cell} ipython3
print(b+b[1:4,:])
```
......@@ -267,11 +268,11 @@ hv.Overlay([list_of_plots])
*Beispiel*:
```{code-cell}
```{code-cell} ipython3
b[5:,:]*b[1:4,:]
```
```{code-cell}
```{code-cell} ipython3
hv.Overlay([
b,
b[1:4]
......@@ -288,7 +289,7 @@ hv.Curve(data, label = "legende")
*Beispiel*:
```{code-cell}
```{code-cell} ipython3
options={'Curve': dict(xticks=[(-np.pi,'pi'), (-np.pi/2,'pi/2'), (0,'0'), (np.pi/2,'pi/2'), (np.pi,'pi')])} #allgemeine optionen
x = np.linspace(-np.pi, np.pi, 100)
......@@ -304,14 +305,14 @@ cos = hv.Curve((x, np.cos(x)),label="cosine").options(
Weiteres Beispiel mit den direkten Operatoren `+` und `*`;
hier reichen wir das holoviews-Objekt direkt weiter an die nächste Funktion:
```{code-cell}
```{code-cell} ipython3
sina = hv.Area(sin)
cosa = hv.Area(cos)
```
`alpha` $\in [0,1]$ Transparenz.
```{code-cell}
```{code-cell} ipython3
options = {'Area': dict(alpha=0.4)}
overlay = (cosa * sina).options(options)
......@@ -337,7 +338,7 @@ die z.B. die Achsen über alle Plots hinweg koppeln.
*Beispiel*: Wir erzeugen uns einen größeren Satz von Kurven, den wir auf verschiedene Weise darstellen wollen. Wir nutzen hier den Sinus mit verschiedenen Frequenzen.
```{code-cell}
```{code-cell} ipython3
frequencies = np.linspace(0,3,10)
def sine_curve(freq):
......@@ -347,13 +348,12 @@ def sine_curve(freq):
curve_dict = {f:sine_curve(f) for f in frequencies}
```
```{code-cell}
```{code-cell} ipython3
%%output size=60
hv.NdLayout(curve_dict, kdims=['frequency'])
```
```{code-cell}
```{code-cell} ipython3
hv.NdOverlay(curve_dict, kdims=['frequency'])
```
......@@ -374,7 +374,7 @@ zeigt einen plot zur gleichen Zeit und gibt die Möglichkeit alle plots durch ei
Nehmen wir das Beispiel von eben und stecken es in
eine HoloMap.
```{code-cell}
```{code-cell} ipython3
frequencies = np.linspace(0,3,10)
def sine_curve(freq):
......@@ -385,6 +385,7 @@ curve_dict = {f:sine_curve(f) for f in frequencies}
hv.HoloMap(curve_dict, kdims=['frequency'])
```
(dynamicmap)=
## Interaktion - DynamicMap
......@@ -397,7 +398,7 @@ DynamicMap(func, **kwargs)
Erzeugen wir ein neues Beispiel:
```{code-cell}
```{code-cell} ipython3
xvals = np.linspace(0,5,100)
def sine_curve(freq):
......@@ -409,7 +410,7 @@ dmap
Da erstmal nur eine Funktion übergeben wurde, ist ohne eine weitere Information, wie diese aufgerufen werden soll, nicht klar, was berechnet werden soll. Das geben wir der Map mit `redim`:
```{code-cell}
```{code-cell} ipython3
dmap.redim.range(frequency=(0,3))
```
......@@ -428,7 +429,7 @@ Auswahl an Optionen (kwargs):
- `color=hv.dim('name')` : setzt die Farbe. Mit `hv.dim` kann die Farbgebung über den Spaltennamen `name` gesetzt werden. Es können beliebige Ausdrücke ausgewertet werden.
- `size=hv.dim('name')` : setzt die Größe.
```{code-cell}
```{code-cell} ipython3
n = 40
x, y = np.random.rand(2, n) # Zufallszahlen 2 x n
......@@ -437,7 +438,6 @@ options = { 'Scatter': dict(show_grid=True, color=hv.dim('z'), size=hv.dim('size
value = 1.0 * np.random.rand(n)
scale = 10.0 * np.random.rand(n)
hv.Scatter((x, y, value, scale), vdims=['y', 'z', 'size']).options(options)
```
## Funktionen $\mathbb{R} \to \mathbb{R}^2$
......@@ -450,7 +450,7 @@ $$
\{(x(t),y(t)) \in \mathbb{R}^2 \;|\; t \in [a,b]\}.
$$
```{code-cell}
```{code-cell} ipython3
def func(t, alpha, beta):
""" Returns coordinate tuple"""
return alpha*np.sin(t+beta)*np.sin(3*t), alpha*np.cos(t+beta)*np.sin(3*t)
......@@ -476,12 +476,12 @@ hv.Image(data, kdims=None, vdims=None, bounds=None, extents=None, xdensity=None,
Plot von $f(x,y)=(1 - x/2 + x^5 + y^3) e^{-(x^2 + y^2)}$:
```{code-cell}
```{code-cell} ipython3
x, y = np.ogrid[-3:3:300j, -2:2:200j]
z = (1 - x/2 + x**5 + y**3) * np.exp(-(x**2 + y**2))
```
```{code-cell}
```{code-cell} ipython3
options = {'Image' : dict(cmap='viridis')}
hv.Image(z).options(options)
......@@ -496,19 +496,19 @@ Die zweite Darstellung entspricht der üblichen Darstellung des Arrays als Matri
`np.ogrid` generiert Koordinaten, die der ersten Konvention entsprechen. Zum Darstellen mit `hv.Image` muss man daher hier die $y$-Achse spiegeln und transponieren.
```{code-cell}
```{code-cell} ipython3
hv.Image(np.flip(z, axis=1).T).options(options)
```
Eine weitere und oft bessere Option ist es, die Achsen explizit mit zu übergeben (als 1d-Arrays), wodurch der `np.flip`-Aufruf weggelassen werden kann. Transponiert werden muss allerdings immer noch:
```{code-cell}
```{code-cell} ipython3
hv.Image((x.ravel(), y.ravel(), z.T)).options(options)
```
### DynamicMap Beispiel
```{code-cell}
```{code-cell} ipython3
xx, yy = np.ogrid[0:10:200j, 0:10:200j]
def cells(time):
......@@ -523,7 +523,7 @@ dmap.redim.range(time=(1,20))
Eigentlich sollten die Werte mit der Zeit größer werden, man sieht davon aber nichts. Wir sollten eine colorbar anschalten. Wir verwenden dafür wieder die .options Methode.
```{code-cell}
```{code-cell} ipython3
options = {'Image' : dict (cmap='viridis', tools=['hover'], colorbar=True)}
dmap.redim.range(time=(1,20)).options(options)
......@@ -531,9 +531,10 @@ dmap.redim.range(time=(1,20)).options(options)
Hier sieht man, dass die Farbskala stets mit angepasst wird, weil es jedesmal ein neues Bild ist. Möchten wir ein konstantes Mapping der Farbe, geben wir ebenfalls durch `redim` der Map eine entsprechende Range:
```{code-cell}
```{code-cell} ipython3
dmap.redim.range(time=(1,20), Intensity=(-20,20)).options(options)
```
(colormaps)=
### colormaps
......@@ -587,40 +588,42 @@ Mit der option `levels` kann man die Anzahl der Konturlinien angeben.
*Beispiel*: Zeichnen der Niveaulinien:
```{code-cell}
```{code-cell} ipython3
options = {'Image' : dict(cmap='viridis')}
img = hv.Image(z).options(options)
img + hv.operation.contours(img, levels=10)
```
```{code-cell}
```{code-cell} ipython3
img * hv.operation.contours(img, levels=10).options( show_legend=False, colorbar=True)
```
```{code-cell}
```{code-cell} ipython3
hv.operation.contours(img, levels=10, filled=True)
```
```{code-cell}
```{code-cell} ipython3
def circle(radius):
angles = np.linspace(0, 2*np.pi, 100)
return {'x': radius*np.sin(angles), 'y': radius*np.cos(angles), 'radius': radius}
hv.Contours([circle(i) for i in np.linspace(0, 1, 10)], vdims='radius')
```
(threshold)=
### Threshold-Plots
Eine ähnliche Darstellungsweise ist der Threshold-Plot.
Hier werden alle Pixel oberhalb bzw. unterhalb eines cutoffs in unterschiedlichen Farben dargestellt.
```{code-cell}
```{code-cell} ipython3
img = hv.Image(z)
percentiles = [np.percentile(z, i) for i in np.linspace(1, 99, 10)]
curve_dict = {p:hv.operation.threshold(img, level= p) for p in percentiles}
hv.HoloMap(curve_dict, kdims=['cutoff'])
```
(vector_plot)=
### Vektorfelder $\mathbb{R}^2 \rightarrow \mathbb{R^2}$
......@@ -639,7 +642,7 @@ angle = (np.pi/2.) - np.arctan2(U/mag, V/mag)
- *color_index:* die Variable, die für die Farb-Abbildung der Vektoren genommen wird
```{code-cell}
```{code-cell} ipython3
x, y = np.ogrid[-3:3:20j, -3:3:20j]
X, Y = np.broadcast_arrays(x, y)
U = -1 - X**2 + Y
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment