[ANN] Makie v0.24

Skia is pretty cool, I’m not sure how well it works for writing out PDFs and SVGs.
If those work well, I guess it could be a pretty nice replacement for CairoMakie.
If it cant replace it, it will be a bit badly positioned between GLMakie and CairoMakie, so it would make it a bit harder to give clear advice on which backend to use.
Anyways, would be nice to have a prototype and see how it does.

PDFs are no problem at all. The same engine is used when you print a web page. The status for SVG:s are more questionable. There is no export page to SVG functionality in most browsers. Export to SVG exists, but it could contain bugs. I will make a prototype, I am certain it will do well.

3 Likes

Hmmm… so simple things like this no longer seem to work now?

s = Scene(camera=cam3d!)

a = Observable(Point3{Float64}(0.0, 0.0, 0.0))
meshscatter!(s, Point3{Float64}(0.0, 0.0, 0.0), marker=lift(a -> Sphere(a, 1.0), a), markersize=1, space=:data)
a[] = Point3(1.0, 1.0, 1.0)  # Update the observable to trigger the meshscatter update
notify(a)


s = Scene(camera=cam3d!)

a = Observable(Point3{Float64}(0.0, 0.0, 0.0))
mesh!(s, lift(a -> Sphere(a, 1.0), a), space=:data)
a[] = Point3(1.0, 1.0, 1.0)  # Update the observable to trigger the meshscatter update
notify(a)

The meshscatter! code does not work. However, I don’t know if this is an inconsistency or if, in that case, that would not be an attribute or whatever, but it works well for mesh!

What would be a simple fix to the code if these kinds of Observable updates are what your code relies on? How exactly would you do this with the ComputeGraph pipeline?

(I know I can use the position to be an observable, but what if I want attributes like marker to be automatically updatable, given some other variable updates?)



using GLMakie


# Create a scene
s = Scene(camera=cam3d!)

# Create the meshscatter plot with an initial static marker
plot = meshscatter!(s, Point(0.0, 0.0, 0.0), marker=Sphere(Point(0.0, 0.0, 0.0), 1.0), markersize=1, space=:data)

# Update the marker using Makie.update!
Makie.update!(plot, marker=Sphere(Point3(2.0, 1.0, 1.0), 1.0)) # Does NOT work as expected, the marker is not updated in the scene
Makie.update!(plot, color=:orange) # Works as expected, the color is updated in the scene
Makie.update!(plot, markersize=2) # Works as expected, the markersize is updated in the scene

typeof(plot.attributes) # returns ComputePipeline.ComputeGraph

plot.attributes
# Returns 
# ComputeGraph():
#   Inputs:
#     :alpha            => Input(:alpha, 1.0)
#     :arg1             => Input(:arg1, [0.0, 0.0, 0.0])
#     :backlight        => Input(:backlight, 0.0)
#     :clip_planes      => Input(:clip_planes, Plane3f[])
#     :color            => Input(:color, orange)
#     :colormap         => Input(:colormap, viridis)
#     :colorrange       => Input(:colorrange, Makie.Automatic())
#     :colorscale       => Input(:colorscale, identity)
#     :cycle            => Input(:cycle, [:color])
#     :cycle_index      => Input(:cycle_index, 1)
#     :depth_shift      => Input(:depth_shift, 0.0)
#     :diffuse          => Input(:diffuse, 1.0)
#     :dim_conversions  => Input(:dim_conversions, Makie.DimConversions((Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing), Observable{Union{Nothing, Makie.AbstractDimConversion}}(nothing))))
#     :f32c             => Input(:f32c, nothing)
#     :fxaa             => Input(:fxaa, true)
#     :highclip         => Input(:highclip, Makie.Automatic())
#     :inspectable      => Input(:inspectable, true)
#     :inspector_clear  => Input(:inspector_clear, Makie.Automatic())
#     :inspector_hover  => Input(:inspector_hover, Makie.Automatic())
#     :inspector_label  => Input(:inspector_label, Makie.Automatic())
#     :interpolate      => Input(:interpolate, true)
#     :lowclip          => Input(:lowclip, Makie.Automatic())
#     :marker           => Input(:marker, Sphere{Float64}([2.0, 1.0, 1.0], 1.0))
#     :markersize       => Input(:markersize, 2)
#     :matcap           => Input(:matcap, nothing)
#     :material         => Input(:material, nothing)
#     :model            => Input(:model, [1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0])
#     :nan_color        => Input(:nan_color, transparent)
#     :overdraw         => Input(:overdraw, false)
#     :palette_lookup   => Input(:palette_lookup, Dict(:color => :color))
#     :palettes         => Input(:palettes, Attributes())
#     :rotation         => Input(:rotation, 0.0)
#     :shading          => Input(:shading, true)
#     :shininess        => Input(:shininess, 32.0)
#     :space            => Input(:space, data)
#     :specular         => Input(:specular, 0.2)
#     :ssao             => Input(:ssao, false)
#     :transform_func   => Input(:transform_func, identity)
#     :transform_marker => Input(:transform_marker, true)
#     :transformation   => Input(:transformation, automatic)
#     :transparency     => Input(:transparency, false)
#     :uv_transform     => Input(:uv_transform, Makie.Automatic())
#     :visible          => Input(:visible, true)

#   Outputs:
#     :alpha                      => Computed(:alpha, 1.0)
#     :alpha_colormap             => Computed(:alpha_colormap, ColorTypes.RGBA{Float32}[RGBA(0.267004, 0.004874, 0.329415, 1.0), RGBA(0.26851, 0.009605, 0.335427, 1.0), RGBA(0.269944, 0.014625, 0.341379, 1.0), RGBA(0.271305, 0.019942, 0.347269, 1.0), RGBA(0.272594, 0.025563, 0.353093, 1.0), RGBA(0.273809, 0.031497, 0.358853, 1.0), RGBA(0.274952, 0.037752, 0.364543, 1.0), RGBA(0.276022, 0.044167, 0.370164, 1.0), RGBA(0.277018, 0.050344, 0.375715, 1.0), RGBA(0.277941, 0.056324, 0.381191, 1.0)  …  RGBA(0.906311, 0.894855, 0.098125, 1.0), RGBA(0.916242, 0.896091, 0.100717, 1.0), RGBA(0.926106, 0.89733, 0.104071, 1.0), RGBA(0.935904, 0.89857, 0.108131, 1.0), RGBA(0.945636, 0.899815, 0.112838, 1.0), RGBA(0.9553, 0.901065, 0.118128, 1.0), RGBA(0.964894, 0.902323, 0.123941, 1.0), RGBA(0.974417, 0.90359, 0.130215, 1.0), RGBA(0.983868, 0.904867, 0.136897, 1.0), RGBA(0.993248, 0.906157, 0.143936, 1.0)])
#     :ambient                    => Computed(:ambient, RGB{Float32}(0.45, 0.45, 0.45))
#     :arg1                       => Computed(:arg1, [0.0, 0.0, 0.0])
#     :args                       => Computed(:args, ([0.0, 0.0, 0.0],))
#     :backlight                  => Computed(:backlight, 0.0)
#     :boundingbox                => Computed(:boundingbox, #undef)
#     :camera_matrix_names        => Computed(:camera_matrix_names, (:world_to_clip, :eye_to_clip, :world_to_eye))
#     :clip_planes                => Computed(:clip_planes, Plane3f[])
#     :color                      => Computed(:color, RGBA{Float32}(1.0, 0.64705884, 0.0, 1.0))
#     :color_mapping              => Computed(:color_mapping, nothing)
#     :color_mapping_type         => Computed(:color_mapping_type, continuous)
#     :colormap                   => Computed(:colormap, viridis)
#     :colorrange                 => Computed(:colorrange, Makie.Automatic())
#     :colorscale                 => Computed(:colorscale, identity)
#     :convert_kwargs             => Computed(:convert_kwargs, NamedTuple())
#     :converted                  => Computed(:converted, (Point{3, Float64}[[0.0, 0.0, 0.0]],))
#     :cycle                      => Computed(:cycle, Cycle([[:color] => :color], false))
#     :cycle_index                => Computed(:cycle_index, 1)
#     :data_limits                => Computed(:data_limits, #undef)
#     :depth_shift                => Computed(:depth_shift, 0.0)
#     :diffuse                    => Computed(:diffuse, Float32[1.0, 1.0, 1.0])
#     :dim_conversions            => Computed(:dim_conversions, #undef)
#     :dim_converted              => Computed(:dim_converted, ([0.0, 0.0, 0.0],))
#     :eyeposition                => Computed(:eyeposition, Float32[3.0, 3.0, 3.0])
#     :f32c                       => Computed(:f32c, nothing)
#     :f32c_scale                 => Computed(:f32c_scale, Float32[1.0, 1.0, 1.0])
#     :fetch_pixel                => Computed(:fetch_pixel, false)
#     :fxaa                       => Computed(:fxaa, true)
#     :gl_len                     => Computed(:gl_len, 1)
#     :gl_renderobject            => Computed(:gl_renderobject, RenderObject(id = 2147484966, visible = true))
#     :highclip                   => Computed(:highclip, Makie.Automatic())
#     :highclip_color             => Computed(:highclip_color, RGBA{Float32}(0.993248, 0.906157, 0.143936, 1.0))
#     :inspectable                => Computed(:inspectable, #undef)
#     :inspector_clear            => Computed(:inspector_clear, #undef)
#     :inspector_hover            => Computed(:inspector_hover, #undef)
#     :inspector_label            => Computed(:inspector_label, #undef)
#     :instances                  => Computed(:instances, 1)
#     :interpolate                => Computed(:interpolate, #undef)
#     :light_color                => Computed(:light_color, RGB{Float32}(0.5, 0.5, 0.5))
#     :light_direction            => Computed(:light_direction, Float32[0.21692765, -0.42907795, -0.87683207])
#     :lowclip                    => Computed(:lowclip, Makie.Automatic())
#     :lowclip_color              => Computed(:lowclip_color, RGBA{Float32}(0.267004, 0.004874, 0.329415, 1.0))
#     :marker                     => Computed(:marker, Mesh{3, Float32, NgonFace{3, OffsetInteger{-1, UInt32}}}(...))
#     :marker_bb                  => Computed(:marker_bb, #undef)
#     :markersize                 => Computed(:markersize, Float32[2.0, 2.0, 2.0])
#     :matcap                     => Computed(:matcap, nothing)
#     :material                   => Computed(:material, #undef)
#     :model                      => Computed(:model, [1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0])
#     :model_f32c                 => Computed(:model_f32c, Float32[1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0])
#     :nan_color                  => Computed(:nan_color, RGBA{Float32}(0.0, 0.0, 0.0, 0.0))
#     :overdraw                   => Computed(:overdraw, false)
#     :packed_uv_transform        => Computed(:packed_uv_transform, Float32[0.0 -1.0 1.0; 1.0 0.0 0.0])
#     :palette_lookup             => Computed(:palette_lookup, Dict(:color => :color))
#     :palettes                   => Computed(:palettes, Attributes())
#     :pattern_uv_transform       => Computed(:pattern_uv_transform, Float32[0.0 -1.0 1.0; 1.0 0.0 0.0])
#     :positions                  => Computed(:positions, Point{3, Float64}[[0.0, 0.0, 0.0]])
#     :positions_transformed      => Computed(:positions_transformed, Point{3, Float64}[[0.0, 0.0, 0.0]])
#     :positions_transformed_f32c => Computed(:positions_transformed_f32c, Point{3, Float32}[[0.0, 0.0, 0.0]])
#     :projection                 => Computed(:projection, Float32[1.8106601 0.0 0.0 0.0; 0.0 2.4142137 0.0 0.0; 0.0 0.0 -1.002002 -1.0402708; 0.0 0.0 -1.0 0.0])
#     :projectionview             => Computed(:projectionview, Float32[-1.2803301 1.2803301 0.0 0.0; -0.98559856 -0.98559856 1.9711971 -2.6803156f-16; -0.5785061 -0.5785061 -0.5785061 4.1662846; -0.57735026 -0.57735026 -0.57735026 5.196152])
#     :raw_color                  => Computed(:raw_color, RGBA{Float32}(1.0, 0.64705884, 0.0, 1.0))
#     :raw_colormap               => Computed(:raw_colormap, ColorTypes.RGBA{Float32}[RGBA(0.267004, 0.004874, 0.329415, 1.0), RGBA(0.26851, 0.009605, 0.335427, 1.0), RGBA(0.269944, 0.014625, 0.341379, 1.0), RGBA(0.271305, 0.019942, 0.347269, 1.0), RGBA(0.272594, 0.025563, 0.353093, 1.0), RGBA(0.273809, 0.031497, 0.358853, 1.0), RGBA(0.274952, 0.037752, 0.364543, 1.0), RGBA(0.276022, 0.044167, 0.370164, 1.0), RGBA(0.277018, 0.050344, 0.375715, 1.0), RGBA(0.277941, 0.056324, 0.381191, 1.0)  …  RGBA(0.906311, 0.894855, 0.098125, 1.0), RGBA(0.916242, 0.896091, 0.100717, 1.0), RGBA(0.926106, 0.89733, 0.104071, 1.0), RGBA(0.935904, 0.89857, 0.108131, 1.0), RGBA(0.945636, 0.899815, 0.112838, 1.0), RGBA(0.9553, 0.901065, 0.118128, 1.0), RGBA(0.964894, 0.902323, 0.123941, 1.0), RGBA(0.974417, 0.90359, 0.130215, 1.0), RGBA(0.983868, 0.904867, 0.136897, 1.0), RGBA(0.993248, 0.906157, 0.143936, 1.0)])
#     :resolution                 => Computed(:resolution, Float32[600.0, 450.0])
#     :rotation                   => Computed(:rotation, 1.0 + 0.0im + 0.0jm + 0.0km)
#     :scaled_color               => Computed(:scaled_color, RGBA{Float32}(1.0, 0.64705884, 0.0, 1.0))
#     :scaled_colorrange          => Computed(:scaled_colorrange, nothing)
#     :scene_origin               => Computed(:scene_origin, #undef)
#     :shading                    => Computed(:shading, true)
#     :shininess                  => Computed(:shininess, 32.0)
#     :space                      => Computed(:space, data)
#     :specular                   => Computed(:specular, Float32[0.2, 0.2, 0.2])
#     :ssao                       => Computed(:ssao, false)
#     :transform_func             => Computed(:transform_func, identity)
#     :transform_marker           => Computed(:transform_marker, true)
#     :transformation             => Computed(:transformation, #undef)
#     :transparency               => Computed(:transparency, false)
#     :uniform_clip_planes        => Computed(:uniform_clip_planes, Vec{4, Float32}[[0.0, 0.0, 0.0, -1.0f9], [0.0, 0.0, 0.0, -1.0f9], [0.0, 0.0, 0.0, -1.0f9], [0.0, 0.0, 0.0, -1.0f9], [0.0, 0.0, 0.0, -1.0f9], [0.0, 0.0, 0.0, -1.0f9], [0.0, 0.0, 0.0, -1.0f9], [0.0, 0.0, 0.0, -1.0f9]])
#     :uniform_num_clip_planes    => Computed(:uniform_num_clip_planes, 0)
#     :upvector                   => Computed(:upvector, Float32[0.0, 0.0, 1.0])
#     :uv_transform               => Computed(:uv_transform, Float32[0.0 -1.0 1.0; 1.0 0.0 0.0])
#     :view                       => Computed(:view, Float32[-0.70710677 0.70710677 0.0 0.0; -0.4082483 -0.4082483 0.8164966 -1.110223f-16; 0.57735026 0.57735026 0.57735026 -5.196152; 0.0 0.0 0.0 1.0])
#     :view_direction             => Computed(:view_direction, Float32[-0.57735026, -0.57735026, -0.57735026])
#     :view_normalmatrix          => Computed(:view_normalmatrix, Float32[-0.7071068 0.7071068 1.4901161f-8; -0.4082483 -0.4082483 0.8164966; 0.5773503 0.5773503 0.5773503])
#     :viewport                   => Computed(:viewport, HyperRectangle{2, Int64}([0, 0], [600, 450]))
#     :visible                    => Computed(:visible, true)
#     :world_normalmatrix         => Computed(:world_normalmatrix, Float32[1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0])

So I can see this changes the inputs, but does not really update the marker? Is this a bug or an intended element?

using GLMakie

s = Scene(camera=cam3d!)

color = Observable(GLMakie.RGBA(1.0, 0.64705884, 0.0, 1.0))  # Observable for the color of the marker

m = meshscatter!(s, Point3(0.0, 0.0, 0.0), marker=Sphere(Point3(0.0, 0.0, 0.0), 1.0), markersize=1, space=:data, color=color[])

on(color) do c
    # Update the marker color whenever the color Observable changes
    Makie.update!(m, color=c)
end

color[] = GLMakie.RGBA(0.0, 1.0, 0.0, 1.0)  # Change the color to green to trigger the update


color[] = GLMakie.RGBA(0.0, 0.0, 1.0, 1.0)  # Change the color to blue to trigger the update


new_pos = Observable(Point3(1.0, 1.0, 1.0))  # Observable for the position of the marker

on(new_pos) do p
    # Update the marker position whenever the position Observable changes
    Makie.update!(m, marker=Sphere(p, 1.0))
end

new_pos[] = Point3(2.0, 2.0, 2.0)  # Change the position to trigger the update

Hmmm… I imagine this is how you would use Observables that are linked to the update! function pipeline that uses ComputeGraphs.

Although, @sdanisch I think the meshscatter marker not changing with the change in an input is a bug. I think I reported this for WGLMakie as well.

Anyways, Great work!

Huh, that seems to be a bug in GLMakie.
But, you can still use plot(...; attribute=observable) without a problem, in fact it pretty much does the on(x-> update!(...), obs), that you’re using.
Explicitly doing on(x-> update!(...), obs) makes mostly sense if you need to update multiple attributes, then its a big improvement!

2 Likes

I see. I will then just use the previous version for my simulation since I rely on that functionality until the bug is fixed.

Interesting, so for optimal runs, I should really stop using Observables as input attributes and call the listener function once for all my updates, which, now I see, is quite simple with the update! function using the new pipeline.

Thanks!