Open CNOT opened 5 years ago
I must admit that would be pretty slick. I would be happy to review a PR, but I'm unlikely to have time to do this myself.
A Gadflyesque way to do this is with a custom statistic (#894). This example will work as is:
module stat
using Measurements, Gadfly
struct MeasurementStatistic <: Gadfly.StatisticElement
end
measurement() = MeasurementStatistic()
# This could all be expanded to handle `x` errors too
Gadfly.Stat.input_aesthetics(stat::MeasurementStatistic) = [:y]
Gadfly.Stat.output_aesthetics(stat::MeasurementStatistic) = [:y, :ymin, :ymax]
Gadfly.Stat.default_scales(stat::MeasurementStatistic) =
[Scale.x_continuous(), Scale.y_continuous()]
function Gadfly.Stat.apply_statistic(stat::MeasurementStatistic,
scales::Dict{Symbol, Gadfly.ScaleElement},
coord::Gadfly.CoordinateElement,
aes::Gadfly.Aesthetics)
dy = Measurements.uncertainty.(aes.y)
aes.y = Measurements.value.(aes.y)
aes.ymin = aes.y - dy
aes.ymax = aes.y + dy
end
end
using Measurements, Gadfly
y = measurement.(10*rand(10), rand(10))
p = plot(x=1:10, y=y,
layer(stat.measurement, Geom.point, Geom.errorbar)
)
Support for Measurements is also another example where chained statistics (#570) would be useful.
It's been awhile since I've looked at Gadfly's codebase. Why does the new statistic need to be a separate layer? Shouldn't it be applied prior to any of the geometries?
I'm not sure I understand why this
p = plot(x=1:10, y=y, stats.measurement, Geom.ribbon)
works, but this
p = plot(x=1:10, y=y, Geom.point, stats.measurement, Geom.ribbon)
doesn't yield a plot?
EDIT: I see your link to the chained statistics PR, is that why?
Interestingly, this seems to work:
There 's an explanation in the docs about layer and statistics here. See text under the "Iris data" plot. Within a layer, all geoms should use the given layer statistic, so try:
layer(stat.measurement, Geom.point, Geom.ribbon)
I should've played around with the code more. It turns out you can't use unitful aesthetics with Geom.ribbon
and that's why I was having issues when applying it to my own data.
What I really like to see is whenever
Gadfly.plot
detects an array ofMeasurement{Float64}
or any other subtype of Real numbers, it automatically plots error bars; similar to howPlots.jl
does it.For the very simplest case something along the following lines would work:
However, this is by no means general, and twiddling a little bit with it, I couldn't make the
splat
to function properly, so it would pipe the rest of the arguments to the insideplot
function.