Temat 6: Wizualizacja danych
Najważniejsze pakiety:
Plots - najpowszechniejsza i bardzo przyjazna w obsłudze PyPlot - interfejs do Matplotliba z Pythona
Makie - rozbudowana biblioteka tworząca wykresy i grafikę wysokiej jakości, rozbudowane opcje 3D
Omówimy tę pierwszą.
Biblioteka Plots oferuje wybór kilku silników graficznych, przełączamy się komendami
pyplot(), gr(), plotly() . Nie wszystkie opcje wykresów są dostępne dla wszystkich, ale te najważniejsze tak.
Opcji i rodzajów wykresów jest w Plots dużo, warto korzystać z oficjalnej dokoumentacji:
http://docs.juliaplots.org/latest/
oraz szczególnie
http://docs.juliaplots.org/latest/attributes/
Wyświetlanie i zapisywanie wykresów
Wiersz komend oraz IDE Julii wyświetlają na ekran ostatni wynik. Jeżeli jest nim wykres, to zostanie wyświetlony.
Zawsze możemy wymusić wyświetlenie wykresu komendą display .
Zawsze możemy zapisać wykres do zmiennej typu Plot i później manipulować nim i wyświetlać go na żądanie. Możemy manipulować wieloma na zmianę.
Domyślnie manipulujemy ostatnim wykresem, który był wyświetlony.
In [1]: using Plots # ładuje Plots
In [2]: plot(1:10) # wyświetlony
5 Out[2]:
In [3]: plot(1:10) # nie wyświetliło, to nie ostatni wynik x = 5
Out[3]:
In [4]: plot(1:10) |> display x = 5
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
5
7 Out[4]:
In [5]: p = plot(1:11,rand(-5:5,11)) x = 7
Out[5]:
In [6]: display(p)
Zapis wykresów
savefig([p::Plot],"nazwa.rozszerzenie")
Domyślnie zapisuje ostatni wyświetlony wykres i umieszcza katalogu roboczym lub jego wskazanym podfolderze.
Aktualny katalog roboczy: komenda pwd() .
Zmiana katalogu roboczego: komenda cd("ścieżka") .
"E:\\Desktop\\Pakiety\\wykłady2021"
Jak wybrać format wykresu
png
+ mały rozmiar pliku + prosty do otwierania - nie skaluje się
svg
+ skaluje się
+ bogate możliwości edycji - trudny do otwierania In [7]: pwd()
Out[7]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
+ prosty do otwierania + skaluje się
- w celu edycji trzeba zmienić format Zwykle dobrym wyborem jest pdf.
Zasady grafiki naukowej
Grafikę naukową dzielimy na 2 dość ogólne rodzaje:
Grafika specjalistyczna/inżynierska:
skierowana do wyrobionego odbiorcy
priorytetem jest dokładność i zakres informacji może operować branożowymi terminami wymaga mniejszej ilości tłumaczeń Grafika popularnonaukowa:
przeznaczona dla ogólnego odbiorcy
priorytetem jest przekazanie najważniejszych idei powinna operować powszechnym słownictwem Priorytety przy tworzeniu grafiki naukowej:
1. Czytelność, jasność przekazu informacji.
2. Stosowanie się do konwencji branżowej.
3. Estetyka, o ile nie wadzi 1. oraz 2.
4. Gust, własne upodobania, o ile nie wadzą 1., 2. oraz 3.
Tworzenie linii
Plots udostępnia 2 podstawowe sposoby:
A. Już znany plot(xs,ys,opcje) In [8]: savefig("myPlot.pdf")
plot(f::Function,a,b,opcje ) Podobnie scatter .
Zaczniemy od B, w nim Julia sama postara się dobrać punkty tak, aby wykres był gładki.
In [9]: plot(sin,-pi,pi)
Out[9]:
In [10]: plot(x->x^2,-2,2)
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Out[10]:
In [11]: plot(x->abs(x^2-1),-2,2, markers=:circle) # dobry
Out[11]:
MethodError: no method matching f(::Float64) Closest candidates are:
f(::Any, ::Any) at In[12]:1 Stacktrace:
[1] (::ComposedFunction{RecipesPipeline.var"#7#8"{Symbol}, typeof(f)})(x::Fl oat64) (repeats 2 times)
@ Base .\operators.jl:938
[2] (::PlotUtils.var"#27#29"{ComposedFunction{ComposedFunction{RecipesPipeli ne.var"#7#8"{Symbol}, typeof(f)}, RecipesPipeline.var"#9#10"{Symbol}}})(x::Flo at64)
@ PlotUtils ~\.julia\packages\PlotUtils\es5pb\src\adapted_grid.jl:46 [3] _broadcast_getindex_evalf
@ .\broadcast.jl:648 [inlined]
[4] _broadcast_getindex
@ .\broadcast.jl:621 [inlined]
[5] getindex
@ .\broadcast.jl:575 [inlined]
[6] macro expansion
@ .\broadcast.jl:984 [inlined]
[7] macro expansion
@ .\simdloop.jl:77 [inlined]
[8] copyto!
@ .\broadcast.jl:983 [inlined]
[9] copyto!
@ .\broadcast.jl:936 [inlined]
[10] copy
@ .\broadcast.jl:908 [inlined]
[11] materialize
@ .\broadcast.jl:883 [inlined]
[12] adapted_grid(f::ComposedFunction{ComposedFunction{RecipesPipeline.var"#7
#8"{Symbol}, typeof(f)}, RecipesPipeline.var"#9#10"{Symbol}}, minmax::Tuple{Fl oat64, Float64}; max_recursions::Int64, max_curvature::Float64)
@ PlotUtils ~\.julia\packages\PlotUtils\es5pb\src\adapted_grid.jl:57 [13] adapted_grid(f::Function, minmax::Tuple{Float64, Float64})
@ PlotUtils ~\.julia\packages\PlotUtils\es5pb\src\adapted_grid.jl:16
[14] _scaled_adapted_grid(f::Function, xscale::Symbol, yscale::Symbol, xmin::
Int64, xmax::Int64)
@ RecipesPipeline ~\.julia\packages\RecipesPipeline\CirY4\src\user_recipe.
jl:353
[15] macro expansion
@ ~\.julia\packages\RecipesPipeline\CirY4\src\user_recipe.jl:293 [inlined]
[16] apply_recipe(plotattributes::AbstractDict{Symbol, Any}, f::Function, xmi n::Number, xmax::Number)
@ RecipesPipeline ~\.julia\packages\RecipesBase\92zOw\src\RecipesBase.jl:2 82 [17] _process_userrecipes!(plt::Any, plotattributes::Any, args::Any)
@ RecipesPipeline ~\.julia\packages\RecipesPipeline\CirY4\src\user_recipe.
jl:36
[18] recipe_pipeline!(plt::Any, plotattributes::Any, args::Any)
@ RecipesPipeline ~\.julia\packages\RecipesPipeline\CirY4\src\RecipesPipel ine.jl:70
[19] _plot!(plt::Plots.Plot, plotattributes::Any, args::Any) @ Plots ~\.julia\packages\Plots\SVksJ\src\plot.jl:172 [20] plot(::Any, ::Vararg{Any, N} where N; kw::Any) @ Plots ~\.julia\packages\Plots\SVksJ\src\plot.jl:58 [21] plot(::Any, ::Any, ::Vararg{Any, N} where N)
@ Plots ~\.julia\packages\Plots\SVksJ\src\plot.jl:52 [22] top-level scope
@ In[12]:3 [23] eval
@ .\boot.jl:360 [inlined]
[24] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::Strin g, filename::String)
@ Base .\loading.jl:1094
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Używając A musimy sami pilnować, aby ilość punktów pozwoliła na uzyskanie gładkiego wykresu.
In [13]: plot(x->f(x,2), 0, 3) # już 1 argumentu, y = 2
Out[13]:
In [14]: t = LinRange(-2,2,10)
plot(t,sin.(1 ./t))
Wykres liniowy vs punktowy
Out[14]:
In [15]: t = LinRange(-2,2,1000) # już dobrze, więcej punktów
plot(t,sin.(1 ./t))
Out[15]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Linii używamy do zaznaczania zjawisk ciągłych, np. teoretycznych przewidywań dla każdego t.
Punktów używamy do zaznaczania zjawisk dyskretnych, np. danych doświadczalnych, pomiarów oddzielonych w czasie. itp.
Wybór zależy od tego, czy ciągła krzywa jest istotną informacją, czy też nie. Ciągła krzywa może być myląca.
Możemy też łączyć jedno i drugie!
In [16]: plot(1:6,factorial.(1:6)) # źle, silnia jest zdefiniowana tylko dla liczb naturalnych!
Out[16]:
In [17]: scatter(1:6,factorial.(1:6)) # dobrze
Wiele linii na jednym wykresie
Dwie najważniejsze metody:
Out[17]:
In [18]: plot(1:6,factorial.(1:6), markers = :circle) # dobrze, o ile chcemy zaznaczyć trend lub coś pod
Out[18]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Dodajemy linie komendami plot!, scatter! lub plot!(p,...), scatter!(p,...) (do wybranego).
Podajemy macierz z wartościami y kolejnych linii.
Przy zbyt dużej ilości wykresy robią się nieczytelne!
In [19]: plot(sin,-pi,pi) plot!(cos,-pi,pi)
Out[19]:
In [20]: xs = LinRange(-pi,pi,500)
ys = zeros(500,2) # 2 kolumny = 2 linie ys[:,1] .= xs .^2
ys[:,2] .= xs .- 1 plot(xs,ys)
Out[20]:
In [21]: scatter(rand(30,40),legend = :none) # 40 serii danych po 30 punktów
# kompletnie nieczytelne Out[21]:
In [22]: plot(rand(30,40),legend = :none)
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Wykresy parametryczne
Różnego rodzaju krzywe często łatwiej jest opisać parametrami nie będącymi . Najprostszym przykładem jest okrąg, który możemy traktować jako zbiór punktów
dla . W takim przypadku zawsze możemy ręcznie stworzyć odpowiednie listy x oraz y jak wcześniej, ale można prościej.
Składnia:
plot(fx::Function, fy::Function, a,b,opcje) fx - funkcja zwracająca x
fy - funkcja zwracająca y a, b - zakres parametru Out[22]:
y= y(x)
x= sin(t), y = cos(t)
−π < t < π
In [23]: plot(cos,sin,-pi,pi, aspectratio=1)
Out[23]:
In [24]: plot(cos,sin,0,pi, aspectratio=1) # pół okręgu, mniejszy zakres parametru
Out[24]:
In [25]: plot([cos, x->cos(x)+1],[sin, x -> sin(x)-1],-pi,pi, aspectratio=1) # dwa na raz
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Wykresy biegunowe
Czyli takie, w których rysujemy jako funkcję . Składnia: wystarczy dodać opcję proj = :polar . Out[25]:
r θ
In [26]: # przykład
θs = LinRange(-2pi,2pi,500) rs = θs .+ 1
plot(θs, rs, proj = :polar)
Modyfikowanie wyglądu wykresów
Out[26]:
In [27]: # funkcyjnie, r = r(theta)
plot(θ->θ,0, 2pi, proj = :polar) # spirala Archimedesa
Out[27]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Jak widzimy wygląd wykresów w Plots zmienia się poprzez modyfikację jego własności, które można wymieniać po przecinkach. Dla przejrzystości warto je wymieniać w nowych liniach.
Opcje zwykle wybieramy symbolami, np. :log10, :red itp.
Rodzaje linii
:solid, :dash, :dot, :dashdot
Różnych rodzajów linii zwykle używamy do zaznaczania różnego typu danych, np. krzywych pomiarowych i teoretycznych.
Grubość linii: linewidth
In [28]: xs = LinRange(-pi,pi,500) ys = sin.(xs)
plot(xs, sin.(xs) .+ 0.1randn(500))
plot!(xs,ys, linestyle = :dash, linewidth = 3) # np. linia teoretyczna i zaszumione dane
# + grubość linii Out[28]:
Rodzaje punktów
Atrybuty markers, markersize, markercolor,markerstrokewidth,markerstrokecolor In [29]: plot(Plots.fakedata(50,1), linecolor = :green) # fałszywe dane do prezentacji
Out[29]:
In [30]: scatter(1:10,rand(0:20,10), markers = :square, markersize = 10,
markercolor = :yellow, markerstrokewidth = 4, markerstrokecolor = :red )
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Zmiany skali
Funkcje, które szybko zanikają lub rosną, nie są dobrze widoczne w standardowej skali. Ważną inżynierską umiejętnością jest właściwy dobór skali do obserwowanej zależności.
Składnia:
yscale = :log10, xscale = :log10 Są też inne skale, ale są mniej ważne.
Co daje zmiana skali:
Niech
wtedy Out[30]:
y= A exp(Bx)
log(y) = Bx + log(A)
Niech b a
In [31]: plot(exp,-5,3)
Out[31]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
In [32]: plot(exp,-5,3, yscale = :log10) # linia prosta, współczynnik kierunkowy = 1, bo to exp(1*x)
Out[32]:
In [33]: plot(x-> exp(-2x),-5,3, yscale = :log10) # wsp. kierunkowy = -2
Out[33]:
In [34]: plot(x-> x^2.5,0,5)
Out[34]:
In [35]: plot(x-> 3x^2.5,0.001,5, xscale=:log10,yscale=:log10) # wsp. kierunkowy to log10(2.5), przebici
Out[35]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
In [36]: plot(x->1/(exp(x)+1),-5,15)
Out[36]:
In [37]: plot(x->1/(exp(x)+1),-5,15, yscale = :log10) # wykładnicza dla dużych x, dokładnie jak exp(-x)
Out[37]:
In [38]: plot(x->exp(x) + 1, -2,2, yscale= :log10) # nie działa, to nie funkcja Aexp(Bx)
Out[38]:
In [39]: # trzeba znaleźć parametr + C i go odjąć
plot(x->exp(x) + 1 - 1, -2,2, yscale= :log10)
Out[39]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
In [40]: plot(x-> exp(-x) + 4, 0, 10) # z dużych x sczytujemy + 4
Out[40]:
In [41]: plot(x-> exp(-x) + 4 - 4, 0, 10, yscale = :log10)
Out[41]:
xlim = (a,b), ylim = (c,d)
Właściwy dobór zakresu ma duże znaczenie dla oddania zmienności!
In [42]: xs = LinRange(-10,10,500) ys = tan.(xs)
plot(xs,ys)
Out[42]:
In [43]: plot(xs,ys, xlim = (-pi,pi), ylim = (-5,5)) # mniejszy zakres - dużo wyraźniej
# linie są połączone, a nie powinny
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Out[43]:
In [44]: # łączenie linii możemy wyłączyć wstawiając NaN
ys[abs.(ys).> 20] .= NaN # wycinamy duże wartości
plot(xs,ys, xlim = (-pi,pi), ylim = (-5,5)) # już nie łączy linii
Out[44]:
Osie wykresu
In [45]: plot(1:10, rand([100, 101],10)) # widzimy dużą zmienność, bo zakres jest od 100 do 101
Out[45]:
In [46]: plot(1:10, rand([100, 101],10), ylim=(0,101)) # tym razem porównujemy zmienność do wartości y,
Out[46]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Składania:
atrybut framestyle , opcje :box, :semi, :origin, :zerolines, :grid, :none .
In [47]: plot(sin,-pi,pi, framestyle = :grid)
Out[47]:
In [48]: plot(sin,-pi,pi, framestyle = :zerolines)
Tekst i komentarze
Wykres należy opisać, obowiązkowe są podpisy osi oraz jednostki.
label - podpis linii xlabel - podpis osi x ylabel - podpis osi y title - tytuł wykresu
annotations, annotate! - dodatkowe komentarze Out[48]:
In [49]: p = plot( # pusty wykres framestyle = :none, xlim = (0,1),
ylim = (0,1) )
for k in 1:500 annotate!(
rand(),rand(), # losowe pozycje text(
rand('a':'z'), # losowa litera
rand([:blue,:pink,:red,:green,:yellow,:orange,:violet,:cyan]) # losowy kolor )
) end
p |> display
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
In [50]: plot(x-> sin(x)^2 + cos(3x), -2pi,2pi, xlabel = "t",
ylabel = "funkcja trygonometryczna", label = "sin(x)^2 + cos(3x)",
title = "nie mam pomysłu"
) Out[50]:
Jako że zajmujemy się matematyką, często w podpisach wykresów będą się pojawiać wyrażenia matematyczne. Julia obsługuje unicode, więc sporo można uzyskać bezpośrednio; potrzebujemy tylko czcionki, która obsługuje potrzebne znaki
In [51]: # szeroki zestaw znaków oferuje PyPlot, więc się na niego przełączmy
pyplot()
plot(x->x^2+5x+6, -3.5,-1.5, title = "x²+5x+6, Δ = 1", label = "parabola"
)
scatter!([-3],[0],
label = "x₁=(-5+√Δ)/2"
)
scatter!([-2],[0],
label = "x₂ = (5+√Δ)/2", legend = :bottomright )
Out[51]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Pakiet LaTeXStrings umożliwia używanie LaTeXa w wykresach. Wystarczy użyć składni L"
tekst $równanie$"
In [52]: gr() # też dobrze, ale trzeba uważać - zależy od dostępności czcionek
plot(x->x^2+5x+6, -3.5,-1.5, title = "x²+5x+6, Δ = 1", label = "parabola"
)
scatter!([-3],[0],
label = "x₁=(-5+√Δ)/2"
)
scatter!([-2],[0],
label = "x₂ = (5+√Δ)/2", legend = :bottomright )
Out[52]:
Wykresy 3D
Krzywe
Krzywe są obiektami jednowymiarowymi. W związku z tym jej naturalnym opisem jest podanie 3 krzywych jednowymiarowych, odpowiadających kolejnym współrzędnym.
In [53]: using LaTeXStrings
pyplot() # gr() nie działa plot([x->1/x, log],1,5,
title = L"fact: $\int_1^x \frac{d y}{y}= \ln(x)$", labels = [L"\frac{1}{x}" L"\ln(x)"],
xlabel = L"x", ylabel = L"y", annotation = (
4,1,
text(L"additionally: $\ln(x) = 2\ln\sqrt{x}$",:green) )
) Out[53]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
In [75]: plotly() # najbezpieczniej plotly t = LinRange(-20,20,10^4)
xs = @. (5+sin(100t))*cos(t) ys = @. (5+sin(100t))*sin(t) zs = @. (5+cos(100t)) + 5t plot(xs,ys,zs,
xlabel = "x", ylabel = "y", zlabel = "z", label=""
) Out[75]:
In [76]: plot(cos,sin,cos,-pi,pi) # funkcyjnie, x = x(t), y = y(t), z = z(t)
Out[76]:
y1
Powierzchnie
Powierzchnie są obiektami 2 wymiarowymi zawieszonymi w 3D. W związku z tym zapisanie ich w postaci 1 wymiarowych tablic jest kłopotliwe (choć możliwe). Wygodniej jest używać macierzy.
Składania:
surface(xs,ys,zs,opcje)
zs - tablica z zetami o współrzędnych odpowiadających tym w xs oraz ys Również
surface(xs,ys,f::Function,opcje) f - funkcja 2 zmiennych
Oprócz tego:
contour - rysuje poziomice
countourf - rysuje wypełnione poziomice heatmap - rysuje wartości komórek bez poziomic
Komenda surface jest efektowna, ale countourf często czytelniejszy!
500×500 Matrix{Float64}:
1.22465e-16 1.22455e-16 1.22426e-16 … 1.22455e-16 1.22465e-16 0.0125912 0.0125902 0.0125872 0.0125902 0.0125912 0.0251804 0.0251784 0.0251725 0.0251784 0.0251804 0.0377657 0.0377627 0.0377537 0.0377627 0.0377657 0.0503449 0.0503409 0.050329 0.0503409 0.0503449 0.0629162 0.0629112 0.0628962 … 0.0629112 0.0629162 0.0754775 0.0754715 0.0754535 0.0754715 0.0754775 0.0880268 0.0880198 0.0879989 0.0880198 0.0880268 0.100562 0.100554 0.10053 0.100554 0.100562 0.113082 0.113073 0.113046 0.113073 0.113082 0.125583 0.125573 0.125543 … 0.125573 0.125583 0.138065 0.138054 0.138021 0.138054 0.138065 0.150524 0.150512 0.150477 0.150512 0.150524 ⋮ ⋱
-0.138065 -0.138054 -0.138021 -0.138054 -0.138065 -0.125583 -0.125573 -0.125543 -0.125573 -0.125583 In [79]: xs = LinRange(-pi,pi, 500)
ys = LinRange(-pi,pi, 500)' # poziomo zs = sin.(xs) .* cos.(ys)
Out[79]:
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
-0.113082 -0.113073 -0.113046 … -0.113073 -0.113082 -0.100562 -0.100554 -0.10053 -0.100554 -0.100562 -0.0880268 -0.0880198 -0.0879989 -0.0880198 -0.0880268 -0.0754775 -0.0754715 -0.0754535 -0.0754715 -0.0754775 -0.0629162 -0.0629112 -0.0628962 -0.0629112 -0.0629162 -0.0503449 -0.0503409 -0.050329 … -0.0503409 -0.0503449 -0.0377657 -0.0377627 -0.0377537 -0.0377627 -0.0377657 -0.0251804 -0.0251784 -0.0251725 -0.0251784 -0.0251804 -0.0125912 -0.0125902 -0.0125872 -0.0125902 -0.0125912 -1.22465e-16 -1.22455e-16 -1.22426e-16 -1.22455e-16 -1.22465e-16 In [80]: surface(xs,ys',zs) # x oraz y pionowo albo wektory 1D
Out[80]:
−1
−0.5 0 0.5 1
In [58]: contour(xs,ys',zs)
Out[58]:
1 2 3
0.4 0.8
In [59]: contourf(xs,ys',zs)
Out[59]:
−3 −2 −1 0 1 2 3
−3
−2
−1 0 1 2 3
−0.8
−0.4 0 0.4 0.8
In [60]: heatmap(xs,ys',zs) # bez konturów
Out[60]:
−2
−1 0 1 2 3
−0.5 0 0.5 1
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
In [61]: # atrybut levels - liczba lub lista poziomic
contourf(xs,ys',zs, levels = 20) # więcej
Out[61]:
−3 −2 −1 0 1 2 3
−3
−2
−1 0 1 2 3
−1
−0.5 0 0.5 1
In [62]: surface(xs,ys',(x,y)->sin(x)*cos(y))
Out[62]:
0.5 1
Możemy zmieniać zestaw barw wykresu, lista jest na https://docs.juliaplots.org/latest/generated /colorschemes/
Komendy:
palette(barwy,n) generuje dyskretny zestaw n barw cgrad(barwy) generuje ciągłe przejście barwne
In [63]: heatmap(xs,ys',zs, c = cgrad(:blues))
Out[63]:
−3 −2 −1 0 1 2 3
−3
−2
−1 0 1 2 3
−1
−0.5 0 0.5 1
In [64]: heatmap(xs,ys',zs, c = cgrad(:greens))
Out[64]:
0 1 2 3
0 0.5 1
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
In [65]: heatmap(xs,ys',zs, c = palette(:greens,5))
Out[65]:
−3 −2 −1 0 1 2 3
−3
−2
−1 0 1 2 3
−1
−0.5 0 0.5 1
In [66]: heatmap(xs,ys',zs, c = cgrad(:greens, [0.2, 0.3, 0.5]))
Out[66]:
2 3
0.5 1
In [67]: # własne skale barw
heatmap(xs,ys',zs, c = palette([:red,:green,:purple,:green,:blue]))
Out[67]:
−3 −2 −1 0 1 2 3
−3
−2
−1 0 1 2 3
−1
−0.5 0 0.5 1
In [68]: heatmap(xs,ys',zs, c = cgrad([:red,:green,:blue,:green,:blue]))
Out[68]:
−1 0 1 2 3
−0.5 0 0.5 1
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Inne przydatne komendy do wizualizacji
Animacja
Makro @animate for ... end zapisuje klatki, które generujemy wykresami i zapisuje do zmiennej.
Komenda gif(animacja, nazwaPliku, fps) tworzy z niego animację.
MethodError: no method matching _show(::IOStream, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PlotlyBackend})
Closest candidates are:
_show(::IO, ::MIME{Symbol("application/vnd.plotly.v1+json")}, ::Plots.Plot{P lots.PlotlyBackend}) at C:\Users\jakub\.julia\packages\Plots\SVksJ\src\backend s\plotly.jl:983
_show(::IO, ::MIME{Symbol("text/html")}, ::Plots.Plot{Plots.PlotlyBackend}) at C:\Users\jakub\.julia\packages\Plots\SVksJ\src\backends\plotly.jl:988
_show(::IO, ::MIME{Symbol("text/html")}, ::Plots.Plot) at C:\Users\jakub\.ju lia\packages\Plots\SVksJ\src\output.jl:165
...
Stacktrace:
[1] show(io::IOStream, m::MIME{Symbol("image/png")}, plt::Plots.Plot{Plots.Pl otlyBackend})
In [69]: a = @animate for theta in LinRange(0,2pi,100) scatter([sin(theta)],[cos(theta)],
markersize = 10, xlim = (-1.1,1.1), ylim = (-1.1,1.1), grid = :off,
ratio = :equal,
framestyle = :origin, label = ""
) end
gif(a,"animacja.gif",fps = 20)
@ .\In[69]:2 [inlined]
[7] top-level scope
@ ~\.julia\packages\Plots\SVksJ\src\animation.jl:183 [8] eval
@ .\boot.jl:360 [inlined]
[9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::Strin g, filename::String)
@ Base .\loading.jl:1094
Przybliżenia
Komndami lens! oraz inset można tworzyć przybliżenia oraz wykresy w wykresie In [70]: plot(x->x^2,-1,1,
legend = :none )
lens!([-1/2, 1/2],[0, 1/4], # co powiększamy
framestyle=:box, # format wykresu przybliżenia
inset=(1, bbox(0.5, 0.0, 0.4, 0.4)) # gdzie jest pudełko z wykresem i jaki ma rozmiar )
Out[70]:
−1.0 −0.5 0.0 0.5 1.0
0.00 0.25 0.50 0.75 1.00
−0.50 −0.25 0.00 0.25 0.50
0.00 0.05 0.10 0.15 0.20 0.25
y1
In [71]: p = plot(sin,-pi,pi,
inset = (1, bbox(0.0, 0.0, 0.4, 0.4)) )
Out[71]:
1.0 y1
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...
Interaktywne wizualizacje i kod
In [72]: plot!(p[2],cos,-pi,pi,color=:red) # p[2] wewnętrznego pudełka
Out[72]:
−3 −2 −1 0 1 2 3
−1.0
−0.5 0.0 0.5 1.0
−3 −2 −1 0 1 2 3
−1.0
−0.5 0.0 0.5
1.0 y1
y2
Pakiet Pluto pozwala obsługiwać interaktywne skoroszyty. Suwaki oraz inne interaktywne elementy można dodawać prostymi fragmentami html, przydatne skróty do nich są w pakiecie
PlutoUI .
W skoroszytach Pluto zmiany dowolnej zmiennej autmatycznie aktualizują wszystkie zmienne z nią związane.
Do tworzenia gadżetów służy makro @bind var gadżet .
Opening http://localhost:1234/?secret=pUmL41P2 in your default browser... ~ ha ve fun!
Press Ctrl+C in this terminal to stop Pluto
Closing Pluto... Restart Julia for a fresh session.
Have a nice day! ���� In [ ]: using Interact, WebIO
@manipulate for x in LinRange(0,25,100) plot(y->sin(y)*sin(x*y),-pi,pi) end
# nie wyświetlam wyniku, nie da się łatwo zapisać do pdf
In [74]: using Pluto
Pluto.run()
Temat 5 http://localhost:8888/nbconvert/html/wykłady2021/Temat 5.ipynb?down...