MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.39k stars 302 forks source link

[Docs] Ideas for additions to docs #307

Closed asinghvi17 closed 1 month ago

asinghvi17 commented 5 years ago

Please put more in the comments!

asinghvi17 commented 5 years ago

Volume plot of 3d function

using AbstractPlotting
AbstractPlotting.__init__();

xs = LinRange(-3, 3, 100);
ys = copy(xs);
zs = copy(xs);

ρ(x, y, z) = exp(-(abs(x)))

qs = [ρ(x, y , z) for x in xs, y in ys, z in zs];

sc = Scene(backgroundcolor = :black)

volume!(sc, xs, ys, zs, qs, algorithm = :mip)

tmp

asinghvi17 commented 5 years ago

this might be cool to show off the abilities of the plotter:

https://github.com/astronexus/HYG-Database

It's a dataset of stars with position, color and magnitude (as well as a host of other things).

Maybe we could replace the stars scatter plot with real stars?

asinghvi17 commented 5 years ago

From the documentation of ColorSchemes.jl (at https://juliagraphics.github.io/ColorSchemes.jl/stable/index.html):

  1. How to use ColorSchemes in Makie:

    using Makie, ColorSchemes
    N = 20
    x = LinRange(-0.3, 1, N)
    y = LinRange(-1, 0.5, N)
    z = x .* y'
    image(x, y, z, colormap = ColorSchemes.picasso.colors)
  2. See all colormaps provided by ColorSchemes.jl

    
    using Makie, ColorSchemes

h = 0.0 offset = 0.1 scene = Scene() cam2d!(scene) plot = map(collect(keys(colorschemes))) do cmap global h c = to_colormap(colorschemes[cmap].colors) cbar = image!( scene, range(0, stop = 10, length = length(c)), range(0, stop = 1, length = length(c)), reshape(c, (length(c), 1)), show_axis = false )[end] text!( scene, string(cmap, ":"), position = Point2f0(-0.1, 0.5 + h), align = (:right, :center), show_axis = false, textsize = 0.4 ) translate!(cbar, 0, h, 0) h -= (1 + offset) end scene

asinghvi17 commented 5 years ago

To document what a Theme is and how it ties in with the Scene (i.e., kwargs are passed from Scene to Theme), we must document what each of these does:

const minimal_default = Attributes(
    palette = default_palettes,
    font = "Dejavu Sans", # font, can be any in system
    backgroundcolor = :white, # color of background
    color = :black, ## color of what?
    colormap = :viridis, # colormap, replicate docs from `Axis`
    marker = Circle, ## what is allowed, what does this do?
    markersize = 0.1, # size of marker
    linestyle = nothing, # in [nothing, :dash, :dot, :dashdot, :dashdotdot], or?
    resolution = reasonable_resolution(), # tuple of resolution, Int, auto determined
    visible = true, ## what?
    clear = true, ## what?
    show_axis = true, # show axes or not
    show_legend = false, ## what?  can we manipulate legend?
    scale_plot = true, ## to what?
    center = true, ## what else?
    axis = Attributes(), ## link to description
    axis2d = Attributes(), ## link to description
    axis3d = Attributes(), ## link to description
    legend = Attributes(), ## what?
    axis_type = automatic, ## 2d or 3d I guess?
    camera = automatic, ## what else can it be?  `campixel!`?
    limits = automatic, # link to HyperRectangle docs
    padding = Vec3f0(0.1), ## pads all around?
    raw = false ## what does it do?
)

(everything with double hashtags needs explanation on what it does, everything with single comments we either have or can link to)

asinghvi17 commented 5 years ago

Speaking of publication quality plots, https://github.com/peterkovesi/PerceptualColourMaps.jl seems good. It would be interesting to see whether it can be made compatible with Makie.

asinghvi17 commented 5 years ago

Documentation on recipes from AbstractPlotting:

Plot Recipes in AbstractPlotting

There's two types of recipes. Type recipes define a simple mapping from a user defined type to an existing plot type. Full recipes can customize the theme and define a custom plotting function.

Type recipes

Type recipe are really simple and just overload the argument conversion pipeline. This can be done for all plot types or for a subset of plot types:

All plot types

`convert_arguments(P::Type{<:AbstractPlot}, x::MyType) = convert_arguments(P, rand(10, 10))`
# Only for scatter plots
`convert_arguments(P::Type{<:Scatter}, x::MyType) = convert_arguments(P, rand(10, 10))`

Optionally you may define the default plot type so that plot(x::MyType) will use this: plottype(::MyType) = Surface

Full recipes with the @recipe macro

A full recipe for MyPlot comes in two parts. First is the plot type name, arguments and theme definition which are defined using the @recipe macro. Second is a custom plot! for MyPlot, implemented in terms of the atomic plotting functions. We use an example to show how this works:

    # arguments (x, y, z) && theme are optional
    @recipe(MyPlot, x, y, z) do scene
        Theme(
            plot_color => :red
        )
    end

This macro expands to several things. Firstly a type definition: const MyPlot{ArgTypes} = Combined{myplot, ArgTypes} The type parameter of Combined contains the function instead of e.g. a symbol. This way the mapping from MyPlot to myplot is safer and simpler. (The downside is we always need a function myplot - TODO: is this a problem?) The following signatures are defined to make MyPlot nice to use: myplot(args...; kw_args...) = ... myplot!(scene, args...; kw_args...) = ... myplot(kw_args::Dict, args...) = ... myplot!(scene, kw_args::Dict, args...) = ... #etc (not 100% settled what signatures there will be) A specialization of argument_names is emitted if you have an argument list (x,y,z) provided to the recipe macro: argument_names(::Type{<: MyPlot}) = (:x, :y, :z) This is optional but it will allow the use of plot_object[:x] to fetch the first argument from the call plot_object = myplot(rand(10), rand(10), rand(10)), for example. Alternatively you can always fetch the ith argument using plot_object[i], and if you leave out the (x,y,z), the default version of argument_names will provide plot_object[:arg1] etc. The theme given in the body of the @recipe invocation is inserted into a specialization of default_theme which inserts the theme into any scene that plots Myplot:

    function default_theme(scene, ::Myplot)
        Theme(
            plot_color => :red
        )
    end

As the second part of defining MyPlot, you should implement the actual plotting of the MyPlot object by specializing plot!:

    function plot!(plot::MyPlot)
        # normal plotting code, building on any previously defined recipes
        # or atomic plotting operations, and adding to the combined `plot`:
        lines!(plot, rand(10), color = plot[:plot_color])
        plot!(plot, plot[:x], plot[:y])
        plot
    end

It's possible to add specializations here, depending on the argument types supplied to myplot. For example, to specialize the behavior of myplot(a) when a is a 3D array of floating point numbers:

    const MyVolume = MyPlot{Tuple{<:AbstractArray{<: AbstractFloat, 3}}}
    argument_names(::Type{<: MyVolume}) = (:volume,) # again, optional
    function plot!(plot::MyVolume)
        # plot a volume with a colormap going from fully transparent to plot_color
        volume!(plot, plot[:volume], colormap = :transparent => plot[:plot_color])
        plot
    end
mkborregaard commented 5 years ago

It'd be obvious to depend on ColorSchemes imho.

SimonDanisch commented 5 years ago

Thanks a lot for getting this started!

Maybe we could replace the stars scatter plot with real stars?

I actually started with that dataset - but took it out when putting it into the gallery :D Large datasets are just so annoying to integrate... Maybe we should have a fetch_data, that downloads or generates random data depending on the context

SimonDanisch commented 5 years ago

PerceptualColorMaps already works just fine:

surface(rand(10, 10), colormap = PerceptualColorMaps.cmap("R3"))
asinghvi17 commented 5 years ago

Thanks a lot for getting this started!

Maybe we could replace the stars scatter plot with real stars?

I actually started with that dataset - but took it out when putting it into the gallery :D Large datasets are just so annoying to integrate... Maybe we should have a fetch_data, that downloads or generates random data depending on the context

I see the issue now...maybe we could just generate random data with random RGBA values and glows? That might look too much like noise, though - maybe we could weight it a bit.

asinghvi17 commented 5 years ago

Here's an idea: why not try to replicate some of the Plots examples in the Makie docs? That way Plots users can transition more smoothly, and some of the more common features will become a bit more obvious.

pbouffard commented 5 years ago

Not sure if this is the right place for it but I have some silly little toy programs that might serve as useful beginner examples. E.g.: https://github.com/pbouffard/miniature-garbanzo/blob/master/robot.jl which looks like this: https://giphy.com/gifs/25JgIK6v56kKIi7CsG. Probably I have a bunch of rookie Julia mistakes in there. If you think it's useful as a demo then hopefully the PR will help me learn what those are! ;)

SimonDanisch commented 5 years ago

@pbouffard that is pretty awesome :) We should definitely make it part of the gallery!

pbouffard commented 5 years ago

The other one currently in that repo (earthmoon.jl) looks like this: https://giphy.com/gifs/348zy5r9Mnd34KEiro

asinghvi17 commented 5 years ago

@pbouffard you should make a PR to MakieGallery! If you take a look at examples/examples3d.jl, you can put:

@block PatrickBouffard ["3d"] begin
    @cell "Robot" [interaction, 3d, lines, slider] begin
    ... # put your code here
    end
end
asinghvi17 commented 5 years ago

Can you update any attribute of a plot's Theme by using scene[end][:something] = something else?

SimonDanisch commented 5 years ago

what do you mean by theme? Just any attribute of a particular plot? If yes, yeah should be... but some attributes sadly don't update right now with GLMakie (e.g. if they change the underlying opengl shader)... Should invest some time at some point to make it consistent, even if it's inefficient

asinghvi17 commented 5 years ago

Do you have a list of which ones don't work?

SimonDanisch commented 5 years ago

attributes: shading, linestyle and then heatmap/image/surface xy ranges get unlifted (woops, that should be easy to fix)

asinghvi17 commented 5 years ago

Perfect, that should get integrated into the updating docs whenever I get around to them.

asinghvi17 commented 5 years ago

@piever, could you give us a list of all the capabilities that StatsMakie has now? I'm not sure which ones are production ready or not. I'd like to flesh out the StatsMakie examples a bit more, with examples of box plots, OHLC, KDE et cetera like what Simon did in MakieThemes' example.

piever commented 5 years ago

That'd be great! StatsMakie is definitely under-documented!

The tutorial includes the "grouping and data" aspect, then there are boxplot and violin (same interface as StatsPlots). corrplot is broken (I was waiting forgrid! to get fixed in Makie but maybe I should give up and implement it with hbox and vbox).

In terms of Analysis (which are stats to do on your data before plotting) there are:

You would basically write plot(density(bandwidth = 0.1), x, y) or something analogous for other Analysis.

In terms of "quality":

Everything else should work well. Feel free to ping me if you open a documentation PR, I'd be happy to help!

asinghvi17 commented 5 years ago

From Slack, thanks to @briochemc:

I specifically struggled with rotating the the "scene" (I used Rotations.jl to make a quaternion to use with rotate! in the end) and zooming in and out (I did not figure that out but I did not need it badly in the end, so I just accepted life without zooming) I think the documentation is a bit sparse. Some functions could help with a bit of explanation. Maybe this could be done with "examples of modifying the existing examples" (like "Placing a title", or "moving a label" , or "Changing the camera angle", or "Zooming in and out", etc.) Also having all the examples in the form of a gallery of images rather than a long list of URLs, something like Tikz Examples (http://www.texample.net/tikz/examples/all/), would be better IMHO. (I think Makie.jl looks great BTW, I don't want to sound like I did not enjoy using it — It allowed me to create what I wanted! :smile:)

He was on the old docs, but this does bring up valid points about rotations and such. The 'gallery of images' thing we already have 😄 but there are still, of course, improvements to be made.

smldis commented 5 years ago

On the raw=true attribute: it just creates the plot object and adds it to the scene...and doesn't do any of the following; calculating limits, making sure that a camera exists, making sure that an axis exists, it doesn't center the view

jane2L commented 5 years ago

Another Idea for addition to docs: I could never find a description for Point2f0() and Point3f0(). Scatter seems not the work with the latter... I don't really know how to use them (how are they understood by the plotting functions?) even though examples are full of them.

SimonDanisch commented 4 years ago

Scatter seems not the work with the latter

That must be a bug or wrong usage... Can you post a minimal example?

asinghvi17 commented 2 years ago

How to move plots between scenes

Let us assume you have located a plot, let's call this p - this could come from p = plot!(...) or p = scene.plots[i] or some other way. There is a scene transfer_scene which you want to transfer this plot to. You can simply do this by push!(transfer_scene, p), which takes care of all the backend features necessary to insert the plot. At worst, simply redisplay it.

Note that you should not do push!(transfer_scene.plots, p), since this does not tell the backend anything.