379 lines
7.7 KiB
Plaintext
379 lines
7.7 KiB
Plaintext
|
# Plots, Datenvisualisierung und Grafik in Julia
|
||
|
|
||
|
|
||
|
- es gibt zahlreiche Pakete, die unterschiedlich geeignet sind je nach
|
||
|
|
||
|
- Ausgabemedium: Grafikkarte, PDF, SVG, PNG, WebApp,....
|
||
|
- Interaktivität
|
||
|
- 2D- und 3D-Fähigkeiten
|
||
|
- Plottypen
|
||
|
- Umgang mit großen Datenmengen
|
||
|
...
|
||
|
|
||
|
|
||
|
Tidier....
|
||
|
|
||
|
## Einbindung anderer Grafikbibliotheken
|
||
|
|
||
|
### JavaScript: Interaktivität im Browser
|
||
|
|
||
|
- [PlotlyJS.jl](http://juliaplots.org/PlotlyJS.jl/stable/examples/3d/) Interface zur PlotlyJS-Grafikbibliothek
|
||
|
- [Bokeh.jl](https://cjdoris.github.io/Bokeh.jl/stable/gallery/) Interface zur Bokeh-Grafikbibliothek
|
||
|
- [VegaLite.jl](https://www.queryverse.org/VegaLite.jl/stable/) Interface zu VegaLite, vor allem statistische Plots
|
||
|
|
||
|
### Cairo: 2D Vektorgrafik, für Grafikkarte (screen), PDF, PNG, SVG,...
|
||
|
|
||
|
- [Luxor.jl](http://juliagraphics.github.io/Luxor.jl/stable/) für Vektorgrafik
|
||
|
- [Javis.jl](https://juliaanimators.github.io/Javis.jl/stable/) für animierte Vektorgrafik
|
||
|
|
||
|
### Matplotlib (Python)
|
||
|
|
||
|
- [PyPlot.jl](https://github.com/JuliaPy/PyPlot.jl)
|
||
|
|
||
|
- weitgehende 1:1-Übertragung der Python-API, deswegen wird auch auf die Matplotlib-Dokumentation verwiesen
|
||
|
- Beispiele mit Gegenüberstellung Python/Julia: [https://gist.github.com/gizmaa/7214002](https://gist.github.com/gizmaa/7214002)
|
||
|
|
||
|
## Pure Julia: Makie.jl
|
||
|
|
||
|
`Makie` bezeichnet sich selbst als _"data visualization ecosystem for Julia"_
|
||
|
|
||
|
Es ist vollständig in Julia geschrieben und bietet als _backends_ `Cairo` (Vektorgrafik), `OpenGL` und `WebGL` an.
|
||
|
|
||
|
|
||
|
- [Makie.jl](https://makie.juliaplots.org/stable/)
|
||
|
- [Beautiful Makie](https://lazarusa.github.io/BeautifulMakie/) eine Seite mit vielen Beispielen
|
||
|
|
||
|
|
||
|
# Plots.jl
|
||
|
|
||
|
```{julia}
|
||
|
using Plots
|
||
|
plotly()
|
||
|
|
||
|
x = 1:33
|
||
|
y = rand(33)
|
||
|
|
||
|
plot(x, y, linecolor =:green, bg_inside =:pink, line =:solid, label = "Wasserstand")
|
||
|
```
|
||
|
|
||
|
- [Plots.jl](https://docs.juliaplots.org/latest/) ist konzipiert als ein einheitliches Interface zu verschiedenen _backends_ (Grafikbibliotheken).
|
||
|
> Man kann zu einem anderen _backend_ wechseln und dieselben Plot-Kommandos und -Attribute verwenden.
|
||
|
|
||
|
- Einige _backends_:
|
||
|
|
||
|
- [GR](https://gr-framework.org/)
|
||
|
- PyPlot (d.h., Matplotlib)
|
||
|
- Plotly(JS)
|
||
|
|
||
|
|
||
|
|
||
|
__Im Rest dieses Notebooks wird Plots.jl vorgestellt.__
|
||
|
|
||
|
|
||
|
## einige _backends_
|
||
|
|
||
|
|
||
|
```julia
|
||
|
using Plots
|
||
|
backend() # Anzeige des gewählten backends, GR ist der default
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
x = 1:30
|
||
|
y = rand(30)
|
||
|
|
||
|
plot(x, y, linecolor =:green, bg_inside =:pink, line =:solid, label = "Wasserstand")
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
# wir wechseln das backend zu
|
||
|
# plotly/js
|
||
|
|
||
|
|
||
|
plotly()
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
# dasselbe Plot-Kommando
|
||
|
|
||
|
# das ist interaktiv (zoom in/out, pan),
|
||
|
# 'überlebt' aber leider die PDF-Konvertierung des notebooks nicht
|
||
|
|
||
|
plot(x, y, linecolor =:green, bg_inside =:pink, line =:solid, label = "Wasserstand")
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
# und noch ein backend
|
||
|
|
||
|
pyplot()
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
plot(x, y, linecolor =:green, bg_inside =:pink, line =:solid, label = "Wasserstand")
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
# zurück zu GR als backend
|
||
|
|
||
|
gr()
|
||
|
```
|
||
|
|
||
|
## Plots.jl und recipes
|
||
|
|
||
|
Andere Pakete können die Möglichkeiten von `Plots.jl` erweitern, indem sie _recipes_ für spezielle Plots und Datenstrukturen definieren, siehe [https://docs.juliaplots.org/latest/ecosystem/](https://docs.juliaplots.org/latest/ecosystem/), z.B.:
|
||
|
|
||
|
- `StatsPlots.jl` direktes Plotten von Dataframes, spezielle statistische Plots,...
|
||
|
- `GraphRecipes.jl` [Plotten von Graphstrukturen](https://docs.juliaplots.org/stable/graphrecipes/examples/)
|
||
|
- ...
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
## Einige Verschönerungen
|
||
|
|
||
|
|
||
|
```julia
|
||
|
using Plots.PlotMeasures # für Angaben in mm, cm,...
|
||
|
using LaTeXStrings # für LaTeX-Konstrukte in Plot-Beschriftungen
|
||
|
using PlotThemes # vorgefertigte Themen
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
# Liste der Themen
|
||
|
keys(PlotThemes._themes)
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
Plots.showtheme(:juno)
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
Plots.showtheme(:dao)
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
# so legt man ein Thema für die folgenden Plots fest:
|
||
|
|
||
|
theme(:dao)
|
||
|
|
||
|
# Wir wollen es wieder langweilig haben...
|
||
|
|
||
|
theme(:default)
|
||
|
```
|
||
|
|
||
|
## Funktionen in Plots.jl
|
||
|
|
||
|
```
|
||
|
plot()
|
||
|
scatter()
|
||
|
contour()
|
||
|
heatmap()
|
||
|
histogram()
|
||
|
bar()
|
||
|
plot3d()
|
||
|
... und weitere
|
||
|
```
|
||
|
Diese Funktionen erzeugen ein neues `Plot`-Objekt.
|
||
|
|
||
|
Die Varianten mit Ausrufezeichen `plot!(), scatter!(),...` modifizieren das letzte `Plot`-Objekt oder das `Plot`-Objekt, das ihnen als 1. Argument übergeben wird:
|
||
|
|
||
|
|
||
|
```julia
|
||
|
x = range(0,10, length=40) # 40 x-Werte von 0 bis 10
|
||
|
|
||
|
pl1 = plot(x, sin.(x))
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
pl1a = deepcopy(pl1) # unmodifizierte copy aufheben
|
||
|
|
||
|
pl2 = plot!(x, cos.(x)) # modifiziert pl1
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
pl3 = scatter!(pl1a, x, cos.(x)) # add to (copy of) original Plot
|
||
|
```
|
||
|
|
||
|
Plot-Objekte kann man als Grafikdateien (PDF, SVG, PNG,...) abspeichern:
|
||
|
|
||
|
|
||
|
```julia
|
||
|
savefig(pl2, "pl2.png")
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
;ls -l pl2.png
|
||
|
```
|
||
|
|
||
|
... oder zB als Sub-Plots mit einem layout-Parameter zusammenfügen:
|
||
|
|
||
|
|
||
|
```julia
|
||
|
plot(pl1, pl2, pl3, layout = (1,3))
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
plot(pl1, pl2, pl3, layout = (3,1))
|
||
|
```
|
||
|
|
||
|
## Input-Daten
|
||
|
|
||
|
- im einfachsten Fall ein Vektor von $m$ `x`-Werten und ein gleichlanger Vektor von $m$ `y`-Werten
|
||
|
- falls $y$ eine $m\times n$-Matrix ist, wird jeder Spaltenvektor als eine `Series` angesehen und es werden $n$ Kurven geplottet:
|
||
|
|
||
|
|
||
|
```julia
|
||
|
|
||
|
plot(x, [sin.(x) cos.(x) sqrt.(x)])
|
||
|
```
|
||
|
|
||
|
|
||
|
- Durch eine `layout`-Angabe kann man die einzelnen `series` auch in einzelnen Subplots
|
||
|
unterbringen.
|
||
|
- Man kann `layouts` auch schachteln und explizite Breiten/Höhenangaben verwenden.
|
||
|
|
||
|
|
||
|
```julia
|
||
|
theme(:dark)
|
||
|
|
||
|
la1 = @layout [
|
||
|
a{0.3w} [ b
|
||
|
c{0.2h} ]
|
||
|
]
|
||
|
|
||
|
plot(x, [sin.(x) cos.(x) sqrt.(x)] , layout = la1)
|
||
|
```
|
||
|
|
||
|
## Plot-Attribute
|
||
|
|
||
|
`Plots.jl` teilt die Attribute in 4 Gruppen ein:
|
||
|
|
||
|
|
||
|
```julia
|
||
|
plotattr(:Plot) # Attribute für den Gesamtplot
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
plotattr(:Subplot) # Attribute für einen Teilplot
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
plotattr(:Axis) # Attribute für eine Achse
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
plotattr(:Series) # Attribute für eine Serie, also zB ein Linienzug im Plot
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
# Zur Erinnerung nochmal:
|
||
|
|
||
|
using Plots
|
||
|
using Plots.PlotMeasures # für Angaben in mm, cm,...
|
||
|
using LaTeXStrings # für LaTeX-Konstrukte in Plot-Beschriftungen
|
||
|
using PlotThemes # vorgefertigte Themen
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
xs = range(0, 2π, length = 100)
|
||
|
|
||
|
data = [sin.(xs) cos.(xs) 2sin.(xs) (x->sin(x^2)).(xs)]
|
||
|
|
||
|
pl10 = plot(xs, data,
|
||
|
fontfamily="Computer Modern",
|
||
|
|
||
|
# LaTeX-String L"" ist im Math-mode
|
||
|
title = L"\textrm{Winkelfunktionen}\ \sin(\alpha), \cos(\alpha), 2\sin(\alpha), \sin(\alpha^2)",
|
||
|
xlabel = L"\textrm{ Winkel\ } \alpha",
|
||
|
ylabel = L"\textrm{Funktionswert}",
|
||
|
|
||
|
# 1x4-Matrizen mit Farben, Marker,... für die 4 'Series'
|
||
|
color=[:black :green RGB(0.3, 0.8, 0.2) :blue ],
|
||
|
markers = [:rect :circle :utriangle :diamond],
|
||
|
markersize = [3 3 0 6],
|
||
|
linewidth = [1 3 1 5],
|
||
|
linestyle = [:solid :dash :dot :solid ],
|
||
|
|
||
|
# Achsen
|
||
|
xlim = (0, 6.6),
|
||
|
ylim = (-2, 2.3),
|
||
|
yticks = -2:.4:2.3,
|
||
|
|
||
|
legend = :bottomleft,
|
||
|
label = [ L"\sin(\alpha)" "cos" "2sin" L"\sin(\alpha^2)"],
|
||
|
|
||
|
top_margin = 5mm,
|
||
|
)
|
||
|
|
||
|
# Zusatzelement
|
||
|
|
||
|
annotate!(pl10, 4.1, 1.8, text("nicht schön, aber viel",10))
|
||
|
|
||
|
```
|
||
|
|
||
|
### Säulendiagramm
|
||
|
|
||
|
|
||
|
|
||
|
```julia
|
||
|
using RDatasets
|
||
|
```
|
||
|
|
||
|
Inhalt: über 700 freie (_"public domain"_) Datensätze, darunter z.B:
|
||
|
|
||
|
- Passagierliste der _Titanic_
|
||
|
- Verbrauchsdaten amerikanischer Autos aus den 70ern
|
||
|
- historische Währungskurse
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
```julia
|
||
|
RDatasets.datasets()
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
cars = dataset("datasets", "mtcars")
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
theme(:bright)
|
||
|
|
||
|
bar(cars.Model, cars.MPG,
|
||
|
label = "Miles/Gallon",
|
||
|
title = "Models and Miles/Gallon",
|
||
|
xticks =:all,
|
||
|
xrotation = 45,
|
||
|
size = [600, 400],
|
||
|
legend =:topleft,
|
||
|
bottom_margin = 10mm
|
||
|
)
|
||
|
|
||
|
```
|
||
|
|
||
|
|
||
|
```julia
|
||
|
|
||
|
```
|