diff --git a/docs/blogposts/v0.20/index.html b/docs/blogposts/v0.20/index.html index db24840..231a630 100644 --- a/docs/blogposts/v0.20/index.html +++ b/docs/blogposts/v0.20/index.html @@ -1,10 +1,10 @@ - - + + - - - + + +
@@ -12,102 +12,102 @@
- - -
- - + + +
+ + -
-
-
-

Makie v0.20

-

We're happy to present you with one of the largest Makie releases we've made to date!

-
+
+
+
+

Makie v0.20

+

We're happy to present you with one of the largest Makie releases we've made to date!

+
-

It was in the works for about a year, a year in which we've had our first Makie conference and saw the adoption of Makie among Julia users rise. One indicator for that is the citation count of our JOSS paper (thank you for acknowledging our work if it benefits you with your own!), which at the moment of writing is - just shy of 100: +

It was in the works for about a year, a year in which we've had our first Makie conference and saw the adoption of Makie among Julia users rise. One indicator for that is the citation count of our JOSS paper (thank you for acknowledging our work if it benefits you with your own!), which at the moment of writing is + just shy of 100:

-
+
-

It's great to flip through all those papers and see how Makie is used in the wild!

-

Version 0.20 will enable users to make even better plots, as it contains many long-awaited features and fixes. So let's take a look at some of the most prominent additions and improvements.

-

Better High DPI support - #2544 & - #2346 +

It's great to flip through all those papers and see how Makie is used in the wild!

+

Version 0.20 will enable users to make even better plots, as it contains many long-awaited features and fixes. So let's take a look at some of the most prominent additions and improvements.

+

Better High DPI support + #2544 & + #2346

-

CairoMakie has long had the ability to increase the resolution of saved images with the - px_per_unit setting. However, GLMakie could only render at exactly the - resolution set in a - Figure or - Scene. This caused several problems: Figures would look too small on high-dpi and too large on low-dpi screens. For inclusion of GLMakie figures in publications, users would have to compute the final resolution for the right dpi count manually, and then adjust all other sizes like fontsize, scatter markers, line widths, etc. to match. +

CairoMakie has long had the ability to increase the resolution of saved images with the + px_per_unit setting. However, GLMakie could only render at exactly the + resolution set in a + Figure or + Scene. This caused several problems: Figures would look too small on high-dpi and too large on low-dpi screens. For inclusion of GLMakie figures in publications, users would have to compute the final resolution for the right dpi count manually, and then adjust all other sizes like fontsize, scatter markers, line widths, etc. to match.

-

Now, GLMakie supports - px_per_unit which means that you can render high-resolution results with a simple - save("output.png", figure, px_per_unit = 5). Interactive windows can automatically adjust their - px_per_unit value to the screen's scaling factor reported by the operating system. This way, Makie windows should always be appropriately sized, with legible, sharp text. +

Now, GLMakie supports + px_per_unit which means that you can render high-resolution results with a simple + save("output.png", figure, px_per_unit = 5). Interactive windows can automatically adjust their + px_per_unit value to the screen's scaling factor reported by the operating system. This way, Makie windows should always be appropriately sized, with legible, sharp text.

-

This effort was spearheaded by Justin Willmert in a heroic and completely unexpected first-contributor effort in - #2544, many thanks to him! +

This effort was spearheaded by Justin Willmert in a heroic and completely unexpected first-contributor effort in + #2544, many thanks to him!

-

With this improvement come a few changes in the API and default Makie theme. The - resolution keyword is deprecated and now called - size, reflecting that this is not a pixel size anymore, even for GLMakie. The default figure size is now - (600, 450) instead of - (800, 600), with a fontsize of - 14 instead of - 16 device-independent pixels (10.5 instead of 12 pt). We do not have to make these sizes a compromise between high-dpi and low-dpi systems anymore, so we felt the default was too large for typical uses in documents or websites. +

With this improvement come a few changes in the API and default Makie theme. The + resolution keyword is deprecated and now called + size, reflecting that this is not a pixel size anymore, even for GLMakie. The default figure size is now + (600, 450) instead of + (800, 600), with a fontsize of + 14 instead of + 16 device-independent pixels (10.5 instead of 12 pt). We do not have to make these sizes a compromise between high-dpi and low-dpi systems anymore, so we felt the default was too large for typical uses in documents or websites.

-

Here's a screenshot from a high-dpi Macbook from the previous Makie version, where you can see that, compared with other apps and system fonts, the window and fontsize used to be pretty small due to unawareness of screen scale factors, which meant that the 800x600 window ended up at a measly 400x300 logical pixels:

-
+

Here's a screenshot from a high-dpi Macbook from the previous Makie version, where you can see that, compared with other apps and system fonts, the window and fontsize used to be pretty small due to unawareness of screen scale factors, which meant that the 800x600 window ended up at a measly 400x300 logical pixels:

+
-

Now, the window has 600x450 logical pixels, backed by 1200x900 actual pixels, so text is sharp and much more readable.

-
+

Now, the window has 600x450 logical pixels, backed by 1200x900 actual pixels, so text is sharp and much more readable.

+
-

Speaking of websites, if you were using Makie on high-dpi screens with web-technology based tools like Pluto, Jupyter notebooks or VSCode, you probably noticed that plots (except for svgs) would often look blurry. Increasing - resolution in GLMakie or - px_per_unit in CairoMakie didn't make the images sharper, just bigger. The reason is that browsers by default display images at their resolution in CSS - px units. On high-dpi screens, one - px unit covers more than one screen pixel, so if you use multiple screen pixels to display one image pixel, you get a blurry result. +

Speaking of websites, if you were using Makie on high-dpi screens with web-technology based tools like Pluto, Jupyter notebooks or VSCode, you probably noticed that plots (except for svgs) would often look blurry. Increasing + resolution in GLMakie or + px_per_unit in CairoMakie didn't make the images sharper, just bigger. The reason is that browsers by default display images at their resolution in CSS + px units. On high-dpi screens, one + px unit covers more than one screen pixel, so if you use multiple screen pixels to display one image pixel, you get a blurry result.

-

Now that we interpret - size of a - Figure in device-independent pixels like CSS, we can display png images with the - text/html MIME type, annotated with the original size via the - width and - height HTML attributes. This way, a - Figure with - size = (600, 450) will display at the same size, no matter how high or low - px_per_unit is set. To give a better default experience, we increased - px_per_unit to - 2 so that outputs in Pluto and other notebooks will look sharp no matter if they're later viewed on a regular or high-dpi screen (at the cost of increased file size). +

Now that we interpret + size of a + Figure in device-independent pixels like CSS, we can display png images with the + text/html MIME type, annotated with the original size via the + width and + height HTML attributes. This way, a + Figure with + size = (600, 450) will display at the same size, no matter how high or low + px_per_unit is set. To give a better default experience, we increased + px_per_unit to + 2 so that outputs in Pluto and other notebooks will look sharp no matter if they're later viewed on a regular or high-dpi screen (at the cost of increased file size).

-

Here's a screenshot from a Macbook running Pluto with the previous Makie v0.19. The default png output is large (800x600 CSS pixels is larger than Pluto's output area size at 700px width, so we're even seeing a slightly scaled-down version). It's not sharp because the image only contains 800x600 pixels while the screen has double the pixels to fill.

-
+

Here's a screenshot from a Macbook running Pluto with the previous Makie v0.19. The default png output is large (800x600 CSS pixels is larger than Pluto's output area size at 700px width, so we're even seeing a slightly scaled-down version). It's not sharp because the image only contains 800x600 pixels while the screen has double the pixels to fill.

+
-

And here is Makie v0.20. The image has the correct size of 600x450 CSS pixels, slightly smaller than Pluto's output area. And it's sharp, because it contains 1200x900 real pixels.

-
+

And here is Makie v0.20. The image has the correct size of 600x450 CSS pixels, slightly smaller than Pluto's output area. And it's sharp, because it contains 1200x900 real pixels.

+
-

Experimental declarative API ( - #3281, - #2868) +

Experimental declarative API ( + #3281, + #2868)

-

Makie has a new - experimental declarative API called - SpecApi. While its interface is not yet stable, we are at a point where we want to ask the community to join forces with us in testing what works and what doesn't, so we're releasing a first version in 0.20. Note that experimental means that we may change this API at any time, so you should not build code intended to have a longer shelf life on top of it, yet. +

Makie has a new + experimental declarative API called + SpecApi. While its interface is not yet stable, we are at a point where we want to ask the community to join forces with us in testing what works and what doesn't, so we're releasing a first version in 0.20. Note that experimental means that we may change this API at any time, so you should not build code intended to have a longer shelf life on top of it, yet.

-

Before going into the details, here is an example of the - SpecApi in use: +

Before going into the details, here is an example of the + SpecApi in use:

-
-
-                using GLMakie
+            
+
+                using GLMakie
 using DelimitedFiles
 using Makie.FileIO
 import Makie.SpecApi as S
@@ -131,40 +131,40 @@ 

Experimental declarative API ( spec_row = S.GridLayout([spec_column_vector spec_matrix], colsizes = [Auto(), Auto(4)]) f, ax, pl = plot(S.GridLayout(spec_row); figure = (; fontsize = 10)) -

+
-

We had been thinking for quite a while about a more declarative API which can describe complex plots as nested dicts without any - Observables. A major issue has been how to keep performant animations part of such an API. The - SpecApi now offers this and allows - Observable{FigureSpec} to create animations of whole layouts and complex plots via diffing. +

We had been thinking for quite a while about a more declarative API which can describe complex plots as nested dicts without any + Observables. A major issue has been how to keep performant animations part of such an API. The + SpecApi now offers this and allows + Observable{FigureSpec} to create animations of whole layouts and complex plots via diffing.

-

There are at least three reasons why Makie can benefit from a declarative API:

-
    -
  1. -

    - AlgebraOfGraphics.jl has never supported animating Plots, because it has been too hard to create complex layouts from data observables in Makie. Since AlgebraOfGraphics is great for interactive data dashboards, this has always been a big limitation. With the new - SpecApi, we will be able to rewrite AlgebraOfGraphics to be just a small generator of - SpecApi objects, with much better compile times and the ability to create fully interactive and performant data dashboards. +

    There are at least three reasons why Makie can benefit from a declarative API:

    +
      +
    1. +

      + AlgebraOfGraphics.jl has never supported animating Plots, because it has been too hard to create complex layouts from data observables in Makie. Since AlgebraOfGraphics is great for interactive data dashboards, this has always been a big limitation. With the new + SpecApi, we will be able to rewrite AlgebraOfGraphics to be just a small generator of + SpecApi objects, with much better compile times and the ability to create fully interactive and performant data dashboards.

    2. -
    3. -

      Pluto and PlutoUI work best with a declarative Plotting API, and it has not been working well with Makie's observable approach. With the - SpecApi this will change and should make the usage of Makie in Pluto much more enjoyable. Note, that the - deeper integration with Pluto will still need some help from Pluto's side. +

    4. +

      Pluto and PlutoUI work best with a declarative Plotting API, and it has not been working well with Makie's observable approach. With the + SpecApi this will change and should make the usage of Makie in Pluto much more enjoyable. Note, that the + deeper integration with Pluto will still need some help from Pluto's side.

    5. -
    6. -

      Nested Dicts will work well for package independent serialization of plots. We could think of serializing complete complex figures to JSON and share them like that. Or we could update figures from within Javascript, making it easier to create animations in plots exported to HTML.

      +
    7. +

      Nested Dicts will work well for package independent serialization of plots. We could think of serializing complete complex figures to JSON and share them like that. Or we could update figures from within Javascript, making it easier to create animations in plots exported to HTML.

    -

    The above JSON export isn't implemented yet, but with this update we're getting a step closer to it.

    -

    To make it easier to work with the - SpecApi, we decided not to use - Dicts but very lightweight structs, which allow us to mirror the default Makie API: +

    The above JSON export isn't implemented yet, but with this update we're getting a step closer to it.

    +

    To make it easier to work with the + SpecApi, we decided not to use + Dicts but very lightweight structs, which allow us to mirror the default Makie API:

    -
    -
    -                import Makie.SpecApi as S # For convenience import it as a shorter name
    +            
    +
    +                import Makie.SpecApi as S # For convenience import it as a shorter name
     S.Scatter(1:4) # create a single PlotSpec object
     
     # Create a complete figure
    @@ -181,24 +181,24 @@ 

    Experimental declarative API ( f

    -

    If only an attribute like a color changes from red to green, Makie will only update that color efficiently. Otherwise, plots and blocks will be deleted and re-created, which is more costly. In general, the - SpecApi will always be slower for animations than using pure - Observables, since we will always pay the cost of finding what has changed (the diffing), but it should be fast enough for lots of use cases. +

    If only an attribute like a color changes from red to green, Makie will only update that color efficiently. Otherwise, plots and blocks will be deleted and re-created, which is more costly. In general, the + SpecApi will always be slower for animations than using pure + Observables, since we will always pay the cost of finding what has changed (the diffing), but it should be fast enough for lots of use cases.

    -

    Usage in - convert_arguments +

    Usage in + convert_arguments

    -

    You can overload - convert_arguments and return an array of - PlotSpecs or a - GridLayoutSpec. The main difference between those is, that returning an array of - PlotSpecs can be plotted like any recipe into axes etc, while overloads returning a whole - GridLayoutSpec can only be plotted to whole layout position (e.g. - figure[1, 1]). +

    You can overload + convert_arguments and return an array of + PlotSpecs or a + GridLayoutSpec. The main difference between those is, that returning an array of + PlotSpecs can be plotted like any recipe into axes etc, while overloads returning a whole + GridLayoutSpec can only be plotted to whole layout position (e.g. + figure[1, 1]).

    -
    -
    -                import Makie.SpecApi as S
    +            
    +
    +                import Makie.SpecApi as S
     struct PlotGrid
         nplots::Tuple{Int,Int}
     end
    @@ -217,49 +217,49 @@ 

    Usage in plot(f[1, 1], PlotGrid((1, 1)); color=Cycled(1)) plot(f[1, 2], PlotGrid((2, 2)); color=Cycled(2)) f -

    +
    -

    You can find more examples in the docs. Note that especially the - convert_argument integration is - experimental and might be moved into another function and work quite differently in the future. Also, you will likely run into some bugs, especially for more complex layouts. +

    You can find more examples in the docs. Note that especially the + convert_argument integration is + experimental and might be moved into another function and work quite differently in the future. Also, you will likely run into some bugs, especially for more complex layouts.

    -

    The PR to introduce the - SpecApi had to fix quite a few internals to make this work: +

    The PR to introduce the + SpecApi had to fix quite a few internals to make this work:

    -
      -
    • -

      Fixes multiple memory leaks for - delete! +

        +
      • +

        Fixes multiple memory leaks for + delete!

      • -
      • -

        Fixes large performance bugs in plot creation. See e.g. - #3307, which was the worst offender. +

      • +

        Fixes large performance bugs in plot creation. See e.g. + #3307, which was the worst offender.

      • -
      • -

        Refactors plot creation API, to make things like - convert_arguments(...)::FigureSpec easier to integrate and removes double - convert_arguments from previous implementation. This will also make Unit support for Axes & Recipes, a.k.a axis converts - #3226 easier. +

      • +

        Refactors plot creation API, to make things like + convert_arguments(...)::FigureSpec easier to integrate and removes double + convert_arguments from previous implementation. This will also make Unit support for Axes & Recipes, a.k.a axis converts + #3226 easier.

      • -
      • -

        Moves cycler from Axis to Scene, so that Recipes and PlotSpec work with cycling, and cycling is applied more consistently.

        -
      • -

        Moves update tracking for the GLMakie - on_demand_renderloop to conversion pipeline, so that less observables for tracking are created (more than halfs the size of objects created for each plot). +

        Moves cycler from Axis to Scene, so that Recipes and PlotSpec work with cycling, and cycling is applied more consistently.

        +
      • +
      • +

        Moves update tracking for the GLMakie + on_demand_renderloop to conversion pipeline, so that less observables for tracking are created (more than halfs the size of objects created for each plot).

      -

      Surface fixes - #2598 +

      Surface fixes + #2598

      -

      This release includes two fixes for surface plots. The first deals with NaN sections in the surface data which previously led to artifacts and lighting bugs across CairoMakie, GLMakie and WGLMakie. They should now consistently be excluded across all backends without lighting issues.

      -
      -
      -                rs = range(-1, 1, length=100)
      +            

      This release includes two fixes for surface plots. The first deals with NaN sections in the surface data which previously led to artifacts and lighting bugs across CairoMakie, GLMakie and WGLMakie. They should now consistently be excluded across all backends without lighting issues.

      +
      +
      +                rs = range(-1, 1, length=100)
       xs = cospi.(rs)
       ys = rs
       zs = [sinpi(x) for x in rs, y in rs]
      @@ -272,13 +272,13 @@ 

      Surface fixes fig

      -

      Improving NaN-related behavior also surfaced a rendering bug which has also been fixed now. Specifically, the vertex positions were placed tightly against the edges like for - image while colors were centered between those vertices like in - heatmap. This resulted in colors at the edge of a surface being constant. The fix is most noticeable with very low-resolution surfaces, where the distances between vertices are large. The difference is almost imperceptible for higher-resolution surfaces, which is why the problem had gone unnoticed for a while. +

      Improving NaN-related behavior also surfaced a rendering bug which has also been fixed now. Specifically, the vertex positions were placed tightly against the edges like for + image while colors were centered between those vertices like in + heatmap. This resulted in colors at the edge of a surface being constant. The fix is most noticeable with very low-resolution surfaces, where the distances between vertices are large. The difference is almost imperceptible for higher-resolution surfaces, which is why the problem had gone unnoticed for a while.

      -
      -
      -                data = [
      +            
      +
      +                data = [
           1 2 3;
           2 2 2;
           3 2 1
      @@ -315,110 +315,110 @@ 

      Surface fixes fig

      -

      Grid conversion Traits - #3106 +

      Grid conversion Traits + #3106

      -

      We have replaced the - SurfaceLike trait and its children - ContinousSurface and - DiscreteSurface with a few new traits. These traits include: +

      We have replaced the + SurfaceLike trait and its children + ContinousSurface and + DiscreteSurface with a few new traits. These traits include:

      -
        -
      • -

        - CellGrid <: GridBased for plots like - heatmap, replacing - DiscreteSurface. It interprets (N, M) input coordinates as centers of cells and outputs (N+1, M+1) coordinates marking the corners of those cells. +

          +
        • +

          + CellGrid <: GridBased for plots like + heatmap, replacing + DiscreteSurface. It interprets (N, M) input coordinates as centers of cells and outputs (N+1, M+1) coordinates marking the corners of those cells.

        • -
        • -

          - VertexGrid <: GridBased for plots such as - surface and - contour. This replaces - ContinuousSurface with the small change that generated x and y values now start at 1 rather than 0. This moves vertices to integer values and makes the respective plots compatible with - heatmap +

        • +

          + VertexGrid <: GridBased for plots such as + surface and + contour. This replaces + ContinuousSurface with the small change that generated x and y values now start at 1 rather than 0. This moves vertices to integer values and makes the respective plots compatible with + heatmap

        • -
        • -

          - ImageLike for - image plots. This conversion trait assumes that the plot is drawn on a regular rectangle, outputting two intervals - xmin..xmax and - ymin..ymax. With no x or y values passed this assumes the 0 as the starting value like - ContinuousSurface did. +

        • +

          + ImageLike for + image plots. This conversion trait assumes that the plot is drawn on a regular rectangle, outputting two intervals + xmin..xmax and + ymin..ymax. With no x or y values passed this assumes the 0 as the starting value like + ContinuousSurface did.

        -
        +
        -

        Camera 3D - #2746 +

        Camera 3D + #2746

        -

        With this update we have merged a number of changes and additions to - Camera3D, the default camera for 3D - Scenes and - LScenes. +

        With this update we have merged a number of changes and additions to + Camera3D, the default camera for 3D + Scenes and + LScenes.

        -
          -
        • -

          Zooming has been reverted from an fov based zoom to a translation of - eyeposition. This removes the change in "perspectiveness" when zooming. +

            +
          • +

            Zooming has been reverted from an fov based zoom to a translation of + eyeposition. This removes the change in "perspectiveness" when zooming.

          • -
          • -

            We added a new interaction which allows you to focus on a geometry by clicking on it with the left alt key pressed.

            -
          • -

            To avoid previous issues with excessive data clipping after zooming, we now have different clipping modes. The default - clipping_mode = :bbox_relative scales - near and - far to be just outside the scenes bounding box while also keeping near in front of the camera. For this to work you may need to call - center!(scene) or - update_cam!(scene[, cam], bbox[, center = true]) explicitly in some cases. Other modes include - :view_relative which scales near and far by - norm(eyeposition - lookat) and - :static which directly passes these values on. -

            +

            We added a new interaction which allows you to focus on a geometry by clicking on it with the left alt key pressed.

          • -
          • -

            Translation speed now scales with the zoom level and fov to feel more consistent.

            +
          • +

            To avoid previous issues with excessive data clipping after zooming, we now have different clipping modes. The default + clipping_mode = :bbox_relative scales + near and + far to be just outside the scenes bounding box while also keeping near in front of the camera. For this to work you may need to call + center!(scene) or + update_cam!(scene[, cam], bbox[, center = true]) explicitly in some cases. Other modes include + :view_relative which scales near and far by + norm(eyeposition - lookat) and + :static which directly passes these values on. +

          • -

            We now take the fov into consideration when centering the camera.

            +

            Translation speed now scales with the zoom level and fov to feel more consistent.

          • -

            We adjusted some of the default key bindings to be more accessible/consistent. These include eyeposition-based zooming changing from page up/down to b/n, and the camera reset changing from the home button to control + left mouse button.

            +

            We now take the fov into consideration when centering the camera.

          • -

            We added - update_cam!(scene[, cam], azimuth, elevation[, radius = current, center = lookat]) which adjusts the camera position according to the given angles. +

            We adjusted some of the default key bindings to be more accessible/consistent. These include eyeposition-based zooming changing from page up/down to b/n, and the camera reset changing from the home button to control + left mouse button.

            +
          • +
          • +

            We added + update_cam!(scene[, cam], azimuth, elevation[, radius = current, center = lookat]) which adjusts the camera position according to the given angles.

          -

          Lighting improvements - #3246, - #3355 +

          Lighting improvements + #3246, + #3355

          -

          We have reworked lighting in GLMakie, adding more light types and allowing for multiple light sources at once, and we have adjusted the default setup across all backends. Furthermore we have made some general improvements to the consistency of lighting between plot types and backends.

          -

          General Changes

          -

          Before this release, the default light setup included an - AmbientLight which sets a base brightness for the scene and a - PointLight which is kept at the camera position. We have changed this to be an - AmbientLight with a - DirectionalLight. A - DirectionalLight works like the sun whose rays are effectively parallel when they arrive on earth. This makes adjusting lighting easier because illumination is the same for all similarly-oriented surfaces in the scene, no matter where they are placed. Before, the default point light was always placed exactly at camera position, which lights everything that the camera can see. Photographers will know that placing a light at camera position removes shadows and therefore depth cues, which is not desirable when we want to assess the three-dimensionality of objects. Our new default directional light now shines down at an angle relative to the camera, which generally makes it easier to see curvature of objects. +

          We have reworked lighting in GLMakie, adding more light types and allowing for multiple light sources at once, and we have adjusted the default setup across all backends. Furthermore we have made some general improvements to the consistency of lighting between plot types and backends.

          +

          General Changes

          +

          Before this release, the default light setup included an + AmbientLight which sets a base brightness for the scene and a + PointLight which is kept at the camera position. We have changed this to be an + AmbientLight with a + DirectionalLight. A + DirectionalLight works like the sun whose rays are effectively parallel when they arrive on earth. This makes adjusting lighting easier because illumination is the same for all similarly-oriented surfaces in the scene, no matter where they are placed. Before, the default point light was always placed exactly at camera position, which lights everything that the camera can see. Photographers will know that placing a light at camera position removes shadows and therefore depth cues, which is not desirable when we want to assess the three-dimensionality of objects. Our new default directional light now shines down at an angle relative to the camera, which generally makes it easier to see curvature of objects.

          -

          We have also adjusted the default values of - diffuse and - specular that a 3D plot carries. They changed from - 0.4 -> 1.0 and - 0.2 -> 0.4 respectively, with light intensities (given through the light color) going down to compensate. This overall makes plots a bit less shiny and cleans up the overexposure you may sometimes see: +

          We have also adjusted the default values of + diffuse and + specular that a 3D plot carries. They changed from + 0.4 -> 1.0 and + 0.2 -> 0.4 respectively, with light intensities (given through the light color) going down to compensate. This overall makes plots a bit less shiny and cleans up the overexposure you may sometimes see:

          -
          -
          -                using Makie.FileIO
          +            
          +
          +                using Makie.FileIO
           
           fig = Figure(backgroundcolor = :black, size = (800, 400))
           
          @@ -447,9 +447,9 @@ 

          General Changes

          fig
          -
          -
          -                rs = range(-1, 1, length=100)
          +            
          +
          +                rs = range(-1, 1, length=100)
           xs = cospi.(rs)
           ys = rs
           zs = [(y + 0.5) * sinpi(x) for x in rs, y in rs]
          @@ -481,9 +481,9 @@ 

          General Changes

          fig
          -
          -
          -                using Makie.FileIO
          +            
          +
          +                using Makie.FileIO
           brain = load(Makie.assetpath("brain.stl"))
           
           fig = Figure(backgroundcolor = :black, size = (800, 400))
          @@ -513,57 +513,57 @@ 

          General Changes

          fig
          -

          And finally we have slightly reworked and cleaned up the - backlight attribute, which allows you to light the backside of a plot with a given weight. It now affects the normals of an object rather than the light direction, which means that specular reflections now work with it. We have also added an attribute conversion so you can now pass any number, not just a Float32. +

          And finally we have slightly reworked and cleaned up the + backlight attribute, which allows you to light the backside of a plot with a given weight. It now affects the normals of an object rather than the light direction, which means that specular reflections now work with it. We have also added an attribute conversion so you can now pass any number, not just a Float32.

          -

          GLMakie Changes (Multiple Lights)

          -

          For GLMakie specifically we have added the option to use multiple lights as well as a number of new light types. One of those is already mentioned above - - DirectionalLight. The full list of available light types is now: +

          GLMakie Changes (Multiple Lights)

          +

          For GLMakie specifically we have added the option to use multiple lights as well as a number of new light types. One of those is already mentioned above - + DirectionalLight. The full list of available light types is now:

          -
            -
          • -

            - AmbientLight(color) which sets a constant base light level (all backends) +

              +
            • +

              + AmbientLight(color) which sets a constant base light level (all backends)

            • -
            • -

              - DirectionalLight(color, direction) which casts parallel light rays in the given direction (all backends) +

            • +

              + DirectionalLight(color, direction) which casts parallel light rays in the given direction (all backends)

            • -
            • -

              - PointLight(color, position[, attenuation]) which casts light originating from the given position with an optional attenuation (distance decay of light intensity). (GLMakie + RPRMakie) +

            • +

              + PointLight(color, position[, attenuation]) which casts light originating from the given position with an optional attenuation (distance decay of light intensity). (GLMakie + RPRMakie)

            • -
            • -

              - SpotLight(color, position, direction, angles) which casts light in a cone shape (GLMakie + RPRMakie) +

            • +

              + SpotLight(color, position, direction, angles) which casts light in a cone shape (GLMakie + RPRMakie)

            • -
            • -

              - RectLight(color, rect, direction) which casts (parallel) light rays through a rectangle (e.g a window, GLMakie) +

            • +

              + RectLight(color, rect, direction) which casts (parallel) light rays through a rectangle (e.g a window, GLMakie)

            • -
            • -

              - EnvironmentLight(intensity, image) which sets an image representing the environment for reflections (i.e. a skybox, RPRMakie) +

            • +

              + EnvironmentLight(intensity, image) which sets an image representing the environment for reflections (i.e. a skybox, RPRMakie)

            -

            To use multiple lights in GLMakie one simply needs to add multiple lights to the - lights vector in a Scene. If this is done before plotting, the - shading attribute will automatically be set to - MultiLightShading which enables multiple lights. (Note that - shading cannot be changed dynamically. It needs to be set when calling - plot!(...).) Once enabled you can add and remove lights, as well as change light attributes like color, position, etc by adjusting the lights in - ax.scene.lights. +

            To use multiple lights in GLMakie one simply needs to add multiple lights to the + lights vector in a Scene. If this is done before plotting, the + shading attribute will automatically be set to + MultiLightShading which enables multiple lights. (Note that + shading cannot be changed dynamically. It needs to be set when calling + plot!(...).) Once enabled you can add and remove lights, as well as change light attributes like color, position, etc by adjusting the lights in + ax.scene.lights.

            -

            Here's how different a simple white meshscatter can look if you add a couple colored lights:

            -
            -
            -                using Random, Statistics
            +            

            Here's how different a simple white meshscatter can look if you add a couple colored lights:

            +
            +
            +                using Random, Statistics
             fig = Figure(backgroundcolor = :black)
             
             # Create lights vector with different light types
            @@ -598,10 +598,10 @@ 

            GLMakie Changes fig

            -

            And here's an example of all light types in one figure:

            -
            -
            -                fig = Figure(backgroundcolor = :black)
            +            

            And here's an example of all light types in one figure:

            +
            +
            +                fig = Figure(backgroundcolor = :black)
             
             # RectLights implement transformations to be a bit easier to handle
             rl = RectLight(RGBf(0.2, 0.8, 0.2), Rect2f(-1, -1, 1, 1))
            @@ -648,36 +648,36 @@ 

            GLMakie Changes fig

            -

            Plot Object refactor

            -

            We refactored the - Combined plot object (which got stuck with a bad name for historical reasons) and finally renamed it to just - Plot. It's now more self contained and one can now create a plot without a scene with the constructor - Plot{plotfunc}(args::Tuple, attributes::Dict), and only later gets the plot connected to a scene. One can also do - lift(func, plotobject, args...), - on(func, plotobject, observable), - onany(func, plotobject, args...) to bind the observable to the lifecycle of a plot. If the plots gets deleted, any observable connection will get cleaned up this way without creating memory leaks. We plan to further build uppon this API, to also add event handling (e.g. - onmouse(callback, plotobject)), in a way that can be better cleaned up and connected to different scenes. +

            Plot Object refactor

            +

            We refactored the + Combined plot object (which got stuck with a bad name for historical reasons) and finally renamed it to just + Plot. It's now more self contained and one can now create a plot without a scene with the constructor + Plot{plotfunc}(args::Tuple, attributes::Dict), and only later gets the plot connected to a scene. One can also do + lift(func, plotobject, args...), + on(func, plotobject, observable), + onany(func, plotobject, args...) to bind the observable to the lifecycle of a plot. If the plots gets deleted, any observable connection will get cleaned up this way without creating memory leaks. We plan to further build uppon this API, to also add event handling (e.g. + onmouse(callback, plotobject)), in a way that can be better cleaned up and connected to different scenes.

            -

            This allows a few things:

            -
              -
            • -

              We called - convert_arguments multiple times in different places in the plotting pipeline, since we didn't have the plot object yet. Now, it gets only called one time. +

              This allows a few things:

              +
                +
              • +

                We called + convert_arguments multiple times in different places in the plotting pipeline, since we didn't have the plot object yet. Now, it gets only called one time.

              • -
              • -

                We don't need to create a temporary scene anymore, just to create a plot. This was done in the pipeline to create a first plot to decide which axis to use, since boundingbox is only defined on complete plot objects.

                -
              • -

                In theory, one can now move plots between scenes/axes more easily, but we haven't implemented an API for this yet.

                +

                We don't need to create a temporary scene anymore, just to create a plot. This was done in the pipeline to create a first plot to decide which axis to use, since boundingbox is only defined on complete plot objects.

              • -

                Better compile times, since the keyword arugments are put into an untyped Dict inside the plot object immediately.

                +

                In theory, one can now move plots between scenes/axes more easily, but we haven't implemented an API for this yet.

                +
              • +
              • +

                Better compile times, since the keyword arugments are put into an untyped Dict inside the plot object immediately.

              -

              Ironically, this refactor removed the reliance on the first plots boundingbox for deciding which axis to use. Instead we now use this overloadable interface:

              -
              -              # no-eval
              +            

              Ironically, this refactor removed the reliance on the first plots boundingbox for deciding which axis to use. Instead we now use this overloadable interface:

              +
              +              # no-eval
               
               Makie.args_preferred_axis([PlotType], plot_arguments...) = PreferredAxisType
               Makie.preferred_axis_type(plot::PlotType) = PreferredAxisType
              @@ -687,12 +687,12 @@ 

              Plot Object refactor

              # Always use LScene for Volume plots preferred_axis_type(::Volume) = LScene
              -

              If no overload is found, we fallback to - Axis. We also introduced - AbstractAxis, which Blocks can inherit from to get all the basic functionality most axes will need (e.g. plotting into them). The default behaviour is defined with these fallbacks (which can be overloaded of course): +

              If no overload is found, we fallback to + Axis. We also introduced + AbstractAxis, which Blocks can inherit from to get all the basic functionality most axes will need (e.g. plotting into them). The default behaviour is defined with these fallbacks (which can be overloaded of course):

              -
              -              # no-eval
              +            
              +              # no-eval
               # falls back to resetting limits
               update_state_before_display!(ax::AbstractAxis) = reset_limits!(ax)
               Makie.can_be_current_axis(ax::AbstractAxis) = true
              @@ -707,10 +707,10 @@ 

              Plot Object refactor

              end figurelike_return(ax::AbstractAxis, plot::AbstractPlot) = AxisPlot(ax, plot)
              -

              All these changes led to significant performance improvements while simplifying the plotting pipeline:

              -

              - image -

              +

              All these changes led to significant performance improvements while simplifying the plotting pipeline:

              +
              + +

              WGLMakie improvements

              • diff --git a/docs/jsserve/png/benchmark-results.png b/docs/jsserve/png/benchmark-results.png new file mode 100644 index 0000000..201b248 Binary files /dev/null and b/docs/jsserve/png/benchmark-results.png differ diff --git a/src/assets/images/benchmark-results.png b/src/assets/images/benchmark-results.png new file mode 100644 index 0000000..201b248 Binary files /dev/null and b/src/assets/images/benchmark-results.png differ diff --git a/src/pages/blogposts/v0.20.md b/src/pages/blogposts/v0.20.md index a698f44..2c0b645 100644 --- a/src/pages/blogposts/v0.20.md +++ b/src/pages/blogposts/v0.20.md @@ -509,7 +509,10 @@ figurelike_return(ax::AbstractAxis, plot::AbstractPlot) = AxisPlot(ax, plot) All these changes led to significant performance improvements while simplifying the plotting pipeline: -![image](https://hackmd.io/_uploads/S1OUyKcXa.png) +```julia +# hide +DOM.img(src=asset("images", "benchmark-results.png")) +``` ## WGLMakie improvements