Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass custom scale in spec or in style? #75

Closed
piever opened this issue Jul 26, 2020 · 3 comments · Fixed by #505
Closed

Pass custom scale in spec or in style? #75

piever opened this issue Jul 26, 2020 · 3 comments · Fixed by #505

Comments

@piever
Copy link
Collaborator

piever commented Jul 26, 2020

Option 1)

style(:SepalLength, :SepalWidth, color = :Species => colorscale) * spec(Scatter)

Option 2)

style(:SepalLength, :SepalWidth, color = :Species) * spec(Scatter, color = colorscale)

For reference, see original discussion, and newer discussion.

@piever
Copy link
Collaborator Author

piever commented Jul 26, 2020

Currently the pair is used to make transformation on the data, for example color = :SepalLength => cut (split into discrete bins the SepalLength). On the other hand, I wonder if this data transformation could somehow be "taken over" by the scale. For example, if I pass a discrete scale, then there is no need to specify that the column is categorical.

@jkrumbiegel
Copy link
Member

jkrumbiegel commented Jul 26, 2020

My thought was that you need some way to specify via AlgebraOfGraphics what type each keyword even maps to. So color in your example maps to colors (could be a Vector{RGBAf0} for example, or a Vector{Float64} with a corresponding colorrange attribute. How much should AoG know about such internal implementations?), but what about markersize or any other keyword where the plotting function expects a certain type and AoG has to map the input type to that output type.

I think that this consideration belongs to the mapping. So to style in the current nomenclature. The full mapping would be Vector{Float64} -> Vector{RGBAf0} for example for some colors, or CategoricalVector{Int} -> Vector{Float64} for some markersizes etc.

Because it would be annoying to specify the full mapping everytime, we could maybe dispatch on keyword symbols and plotting functions to give defaults for this mapping.

Something like

style(:SepalLength, :SepalWidth, color = :Species)

# then internally

default_scale(::Val{:color}, plot_type) = colorscale(:linear, palette = default_palette())

# but instead the user could also do

style(:SepalLength, :SepalWidth, color = :Species => colorscale(:log, palette = :Blues())

@piever
Copy link
Collaborator Author

piever commented Jul 26, 2020

MakieThemes should provide a few default themes, but we should also make sure that it's easy to customize. I would just use a dictionary rather than a method table, but that's just an implementation detail.

I'm starting to get convinced that one can just pass scales to style, but I guess the tricky bit is what information should a Scale have.

First of all, it needs to:

  • specify whether the data is discrete or continuous (numeric data is continuous, and everything else is discrete, but the user needs a way to signal that they are treating a vector of numbers as a discrete column),
  • specify a function transformation.

Then, the discrete scale would receive the value and the list of unique values and will spit out a result. The continuous scale will receive a value and the extrema and spit out the result. I imagine a function could be assumed to be continuous, and discrete things would have a discrete wrapper, or something like that.

Finally, each scale should decide whether the limits (or, in the discrete case, the list of unique values) are from all layers, or only from the layers with the same LAxis. Right now I confess I'm somewhat inconsistent (discrete scales are shared, but the x axis for example are independent). GGPlot2 allows both with a scales = "free" API (see here).

It would actually be easier to not support scales = "free" at all (and link all axes in the facet plot). Do you have any good idea of a sensible API for this? Or do you think we don't need to support "free scales", and all scales (including the axes) should have the same limits across facets? Maybe being "free" could just be a trait of the scale.

Alternatively, each scale could receive the list of unique value per LAxis and then decide what to do. The evil plan is to leave as much freedom as possible to the scale, so that users can create their own, and these scales don't need to be in AlgebraOfGraphics.

@jkrumbiegel jkrumbiegel linked a pull request Jul 16, 2024 that will close this issue
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants