Code Monkey home page Code Monkey logo

Comments (9)

KronosTheLate avatar KronosTheLate commented on June 24, 2024 1

Noted, and completely fair. I hope someone from Makie could help out. If not, ill probably get around to learning how to fix it at some point.

from measurements.jl.

leonvonrabenmond avatar leonvonrabenmond commented on June 24, 2024 1

I think having a way to let Makie.jl know that scatter(m::AbstractVector{<:Measurement}) -> errorbar + scatter and line -> band+line would be really neat!

I totally agree with you and that was my first thought in fixing this as well, but this leads to a new problem: How do we deal with arguments? For example, I dislike errorbars with whiskerwidth = 0, which is the default. While this approach would allow us to put arguments for scatter, it would as far as I can tell not allow us to place any arguments for errorbars.

I think a combination of both of your solutions might be best. To allow the standard plotting functions to take measurement inputs and to define a new functions which allow us to customise the combined output. This is the best approach I can see at this point in time, but I am far from an expert in Makie.

from measurements.jl.

giordano avatar giordano commented on June 24, 2024

I never got Makie working so it's highly unlikely I'll work on that myself. I thought Makie used the same plotting recipes as Plots?

from measurements.jl.

KronosTheLate avatar KronosTheLate commented on June 24, 2024

I never got Makie working so it's highly unlikely I'll work on that myself. I thought Makie used the same plotting recipes as Plots?

I also though so, but I does not work out-the box as with Plots.jl. So something is different.

from measurements.jl.

giordano avatar giordano commented on June 24, 2024

Well, you need someone who can use Makie and cares about this package. It won't be me though 🙂 (but ideally, a single solution that works for both Plots and Makie would be best)

from measurements.jl.

icweaver avatar icweaver commented on June 24, 2024

Would a few simple type recipes be a start possibly? I'm still learning about full recipes, but something like this seems to work pretty well:

using CairoMakie
using Measurements
import Measurements: value, uncertainty

Makie.convert_arguments(P::PointBased, v::Vector, m::AbstractVector{<:Measurement}) = 
convert_arguments(P, v, value.(m))
Makie.convert_arguments(P::Type{<:Errorbars}, v::Vector, m::AbstractVector{<:Measurement}) = 
convert_arguments(P, v, value.(m), uncertainty.(m))

fig = Figure()

x = rand(10) |> sort
y = rand(10) .± rand(0:0.01:1, 10)

scatter(fig[1, 1], x, y)
lines(fig[2, 1], x, y)
scatterlines(fig[1, 2], x, y)
errorbars(fig[2, 2], x, y)
scatter!(fig[2, 2], x, y)

axs = reshape(copy(fig.content), 2, 2)
linkaxes!(axs...)
hidexdecorations!.(axs[begin, :])
hideydecorations!.(axs[:, end])

fig

6d6494ad-ec28-4afc-aabd-bd8a960e3c78

from measurements.jl.

KronosTheLate avatar KronosTheLate commented on June 24, 2024

Last time I tried looking into this, it seemed as if recipes did not work properly in Makie. It was a WIP.

But your example definitely looks functional! Nice ^_^ Personally, I was imagining something like scatter producing a scatter+errorbars, and lines producing a shaded area around the line representing 1 standard deviation, when the uncertanty is on the y values. I don't know what would be best for a potential x value uncertanty in a lines plot.

But your approach definitely seems more modular, which I like! One would e.g. choose how many standard deviations should be represented by the shaded area, and simply layer the uncertainty and means values on top of each other, as you have.

from measurements.jl.

icweaver avatar icweaver commented on June 24, 2024

I think having a way to let Makie.jl know that scatter(m::AbstractVector{<:Measurement}) -> errorbar + scatter and line -> band+line would be really neat! I'm not aware of a way to do this though, so in the meantime this is just my current attempt at trying to accomplish the same thing with a super bare-bones dedicated full recipe for each:

using CairoMakie
using Measurements
import Measurements: value, uncertainty

@recipe(Scatterbars) do scene
    Attributes(;)
@recipe(BandLines) do scene
    Attributes(;)

function Makie.convert_arguments(::Type{<:Scatterbars},  v::Vector, m::AbstractVector{<:Measurement})
    v, value.(m), uncertainty.(m)
end

function Makie.convert_arguments(::Type{<:BandLines},  v::Vector, m::AbstractVector{<:Measurement})
    v, value.(m), uncertainty.(m)
end

function Makie.plot!(plot::Scatterbars{T}) where T <: Tuple{Vector, Vector, Vector}
    x, y, y_err = plot[1][], plot[2][], plot[3][]
    errorbars!(plot, x, y, y_err)
    scatter!(plot, x, y)
    plot
end

function Makie.plot!(plot::BandLines{T}) where T <: Tuple{Vector, Vector, Vector}
    x, y, y_err = plot[1][], plot[2][], plot[3][]
    band!(plot, x, y - y_err, y + y_err, color=(:blue, 0.25))
    lines!(plot, x, y)
    plot
end

fig = Figure()
ax_sb, ax_bl = Axis(fig[1, 1]), Axis(fig[1, 2])

x = rand(10) |> sort
y = rand(10) .± rand(0:0.01:0.1, 10)

scatterbars!(ax_sb, x, y)
bandlines!(ax_bl, x, y)

axs = reshape(copy(fig.content), 1, 2)
linkaxes!(axs...)
hideydecorations!.(axs[:, end])

fig

96f297bb-aaac-421c-adc3-575f138ce61d

There's definitely a lot more that could be done to make this more customizable, but I'm wondering if we'd even want to have separately named specialty functions like these in the first place

from measurements.jl.

leonvonrabenmond avatar leonvonrabenmond commented on June 24, 2024

So I played around with the pure conversion and ended up with:

using MakieCore
using Measurements
import Measurements: value, uncertainty

# PointBased plots
MakieCore.convert_arguments(P::PointBased, x::AbstractVector{<:Measurement}, y::AbstractVector{<:Measurement}) =
    convert_arguments(P, value.(x), value.(y))
MakieCore.convert_arguments(P::PointBased, x::AbstractVector{<:Real}, y::AbstractVector{<:Measurement}) = 
    convert_arguments(P, x, value.(y))
MakieCore.convert_arguments(P::PointBased, x::AbstractVector{<:Measurement}, y::AbstractVector{<:Real}) = 
    convert_arguments(P, value.(x), y)

# errorbars
MakieCore.convert_arguments(P::Type{<:Errorbars}, x::AbstractVector{<:Measurement}, y::AbstractVector{<:Measurement}, e::AbstractVector{<:Measurement}) = 
    convert_arguments(P, value.(x), value.(y), uncertainty.(e))
MakieCore.convert_arguments(P::Type{<:Errorbars}, x::AbstractVector{<:Measurement}, y::AbstractVector{<:Real}) = 
    convert_arguments(P, value.(x), y, uncertainty.(x))
MakieCore.convert_arguments(P::Type{<:Errorbars}, x::AbstractVector{<:Real}, y::AbstractVector{<:Measurement}) = 
    convert_arguments(P, x, value.(y), uncertainty.(y))

# band
MakieCore.convert_arguments(P::Type{<:Band}, x::AbstractVector{<:Measurement}, y::AbstractVector{<:Measurement}) = 
    convert_arguments(P, value.(x), value.(y) - uncertainty.(y), value.(y) + uncertainty.(y))
MakieCore.convert_arguments(P::Type{<:Band}, x::AbstractVector{<:Real}, y::AbstractVector{<:Measurement}) = 
    convert_arguments(P, x, value.(y) - uncertainty.(y), value.(y) + uncertainty.(y))

This converts the cases in which x, y or both have errors. I also made a few assumptions regarding these cases. For errorbars, if only one axis has errors, these are plotted automatically (though direction = :x may have to be specified). If both axis have errors, then the axis has to be specified (as this allows for x-errors).

In case of bands the y-error gets plotted automatically, while the x-error (if present) gets ignored.

I tested this on some old data of mine:

using DataFrames, CairoMakie, Measurements

df = DataFrame("α" => ((0:30:180) .± 5), "U" => ([1.70 ± 0.02, 1.50 ± 0.02, 0.864 ± 0.01, 0.103 ± 0.05, 0.888 ± 0.02, 1.46 ± 0.01, 1.70 ± 0.02]/2))

fig = Figure()

ax1 = Axis(fig[1,1])
errorbars!(ax1, df.α, df.U, df.U)
errorbars!(ax1, df.α, df.U, df.α, direction =:x)
scatter!(ax1, df.α, df.U)

ax2 = Axis(fig[1,2])
band!(ax2, df.α, df.U)
lines!(ax2, df.α, df.U)

fig

fig

So, this works as a basic system and allow us to deal with all types of errors, that I at least have encountered. My question now is, do we actually want plots like scatterbars or linesband? While yes, they would make plotting quicker, it would mess with any form of customisation. We would have to pass arguments for both plot-types, which I don't see how to do elegantly.

In the case that someone does not want to customise the plots a lot, this would be useful, but then we would have to agree on a basic look first. I doubt that the "normal" linesband as in ax2 is something anyone would want to use.

I think we should maybe just do it like this here? Making separate plot types would be more work then just doing two separate plots on the same axis. What do you think?

I think a combination of both of your solutions might be best. To allow the standard plotting functions to take measurement inputs and to define a new functions which allow us to customise the combined output. This is the best approach I can see at this point in time, but I am far from an expert in Makie.

On second thought, I take this back. I think just doing it with simple conversion might really be the best option.

from measurements.jl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.