Julia Users Berlin / Mar 18 2019
Makie Demo
using WebSockets, WebIO, Colors, ImageMagick using CSSUtil, Makie using ImageFiltering, JSExpr using Base64, FixedPointNumbers using ImageTransformations
1. Goals
- Interactivity
- High Performance
- Easy Syntax
- Inbuild Widgets
- sane processing pipeline
2. Recipes
- final API still in flux, but everything is a recipe in Makie
- backwards compatibility to Plots.jl
3. Theming
- every attribute is theme-able
using MakieThemes, AbstractPlotting, Makie, MakieThemes Makie.hbox( Makie.vbox(show_ggthemr(:light), show_ggthemr(:pale)), Makie.vbox(show_ggthemr(:fresh), show_ggthemr(:sea)), )
9.9s
GLMakie (Julia)GLMakie compile
using CSV, StatsMakie using Makie: vbox, hbox data_folder = joinpath(dirname(pathof(MakieThemes)), "..", "data") for dataset ∈ (:www, :drivers, :mtcars, :diamonds) data = CSV.read( joinpath(data_folder, string(dataset, ".tsv")), delim = '\t', allowmissing = :none ) $(dataset) = $data end AbstractPlotting.set_theme!(ggthemr(:fresh)) p1 = scatterlines( Data(www), :Minute, :Users, Group(color = :Measure, marker = :Measure), markersize = 2 ) p2 = plot( density, Data(mtcars), :mpg, Group(color = :cyl) ) p3 = plot( Position.stack, histogram, Data(diamonds), :price, Group(color = :cut) ) p4 = boxplot(Data(drivers), :Year, :Deaths); vbox(hbox(p1, p2), hbox(p3, p4))
using LinearAlgebra n = 20 f = (x,y,z) -> x*exp(cos(y)*z) ∇f = (x,y,z) -> Point3f0(exp(cos(y)*z), -sin(y)*z*x*exp(cos(y)*z), x*cos(y)*exp(cos(y)*z)) ∇ˢf = (x,y,z) -> ∇f(x,y,z) - Point3f0(x,y,z)*dot(Point3f0(x,y,z), ∇f(x,y,z)) θ = [0;(0.5:n-0.5)/n;1] φ = [(0:2n-2)*2/(2n-1);2] x = [cospi(φ)*sinpi(θ) for θ in θ, φ in φ] y = [sinpi(φ)*sinpi(θ) for θ in θ, φ in φ] z = [cospi(θ) for θ in θ, φ in φ] pts = vec(Point3f0.(x, y, z)) ∇ˢF = vec(∇ˢf.(x, y, z)) .* 0.1f0 Makie.surface(x, y, z, resolution = (800,800)) arrows!(pts, ∇ˢF, arrowsize = 0.04, linecolor = (:white, 0.6), linewidth = 1)
4. Interaction
1.0s
GLMakie (Julia)GLMakie compile
AbstractPlotting.set_theme!() # reset theme function lorenz(t0, a, b, c, h) Point3f0( t0[1] + h * a * (t0[2] - t0[1]), t0[2] + h * (t0[1] * (b - t0[3]) - t0[2]), t0[3] + h * (t0[1] * t0[2] - c * t0[3]), ) end # step through the `time` function lorenz(array::Vector, a = 5.0 ,b = 2.0, c = 6.0, d = 0.01) t0 = Point3f0(0.1, 0, 0) for i = eachindex(array) t0 = lorenz(t0, a,b,c,d) array[i] = t0 end array end a = Interact.slider(0f0:50f0, label = "a", value = 13) b = Interact.slider(-20f0:20f0, label = "b", value = 10) c = Interact.slider(0f0:20f0, label = "c", value = 2) d = Interact.slider(LinRange(0.0, 0.02, 100), label = "d", value = 0.01676) scales = Interact.slider(LinRange(0.01, 0.5, 100), label = "scale", start = 0.1) rotation = Interact.slider(LinRange(0, 2pi, 360), label = "rotation") mcolor = widget(colorant"red") n1, n2 = 18, 30 N = n1*n2 args_n = observe.((a, b, c, d)) v0 = lorenz(zeros(Point3f0, N), to_value.(args_n)...) positions = lift(lorenz, Makie.Node(v0), args_n...) mscene = meshscatter( positions, markersize = scales, intensity = collect(range(0f0, stop = 1f0, length = length(positions[]))), color = mcolor, center = false ) center!(mscene) lastval = Ref(rotation[]) on(rotation) do x global lastval rotate_cam!(mscene, lastval[] - x, 0.0, 0.0) lastval[] = x end upsignal = Observables.async_latest(lift(positions, observe(rotation), mcolor, observe(scales)) do a... end) up_scene = lift(x-> Makie.GLMakie.scene2image(mscene), upsignal) CSSUtil.vbox(a, b, c, d, scales, rotation, mcolor, up_scene)
5. Makie & Cairo backend without GPU
using AbstractPlotting, CairoMakie r = range(-10, stop = 10, length = 512) z = ((x, y)-> sin(x) + cos(y)).(r, r') contour(r, r, z, levels = 5, color = :viridis, linewidth = 3)
r = range(-5, stop = 5, length = 400) (a, b) = -1, 2 z = ((x,y) -> y.^4 - x.^4 + a .* y.^2 + b .* x.^2).(r, r') z2 = z .* (abs.(z) .< 250) contour(r, r, z2)
5.1. The Makie Gallery
HTML(read(download("https://simondanisch.github.io/ReferenceImages/gallery/index.html"), String))