--- engine: julia --- ```{julia} #| error: false #| echo: false #| output: false using InteractiveUtils ``` # Plots, Datenvisualisierung und Grafik in Julia Es gibt zahlreiche Grafikpakete für Julia. Das Folgende ist nur eine kleine Auswahl. ## Reines 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://docs.makie.org/stable/) - [Beautiful Makie](https://beautiful.makie.org/) - eine Seite mit vielen Beispielen ## Einbindung anderer Grafikbibliotheken Viele Pakete liefern ein Interface zu existierender hochwertiger Visualisierungsssoftware. ### JavaScript: Interaktive Plots und Visualisierungen 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 In der Regel kann man die Grafiken auch in ein Bildformat wie PNG exportieren. ### Cairo: 2D Vektorgrafik - [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](https://matplotlib.org/stable/gallery/index.html) verwiesen - Beispiele mit Gegenüberstellung Python/Julia: [https://gist.github.com/gizmaa/7214002](https://gist.github.com/gizmaa/7214002) ### ggplot2 (R) - [TidierPlots.jl](https://github.com/TidierOrg/TidierPlots.jl) "is a 100% Julia implementation of the R package ggplot2 powered by Makie.jl." ## 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 ```