Skip to content

Commit

Permalink
Merge pull request #1105 from non-Jedi/fix_unitful
Browse files Browse the repository at this point in the history
Enable plotting of Unitful values
  • Loading branch information
bjarthur authored Dec 16, 2018
2 parents 7c6e899 + e5436d0 commit 2dfff47
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 31 deletions.
14 changes: 6 additions & 8 deletions src/geom/hvabline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,15 @@ function render(geom::ABLineGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthetic
# the line extends to the edges of the graph.

if typeof(aes.y) <: Array{Function}
low, high = aes.xmin[1], aes.xmax[1]
lowx, highx = aes.xmin[1], aes.xmax[1]
else
xextrema = extrema(aes.x)
yextrema = extrema(aes.y)
low = min(xextrema[1], yextrema[1])
high = max(xextrema[2], yextrema[2])
lowx, highx = extrema(aes.x)
end

range = high-low
x0 = low-range
x1 = high+range
# extending the line to width 3 times x-range of data should be enough
rangex = highx - lowx
x0 = lowx - rangex
x1 = highx + rangex

y0s = [x0 * m + b for (m,b) in zip(aes.slope, aes.intercept)]
y1s = [x1 * m + b for (m,b) in zip(aes.slope, aes.intercept)]
Expand Down
27 changes: 7 additions & 20 deletions src/scale.jl
Original file line number Diff line number Diff line change
Expand Up @@ -600,26 +600,13 @@ const color_continuous_gradient = color_continuous ### WHY HAVE THIS ALIAS?

function apply_scale(scale::ContinuousColorScale,
aess::Vector{Gadfly.Aesthetics}, datas::Gadfly.Data...)
cmin, cmax = Inf, -Inf
for data in datas
data.color === nothing && continue

for c in data.color
ismissing(c) && continue

c = convert(Float64, c)
if c < cmin
cmin = c
end

if c > cmax
cmax = c
end
end
cdata = skipmissing(Iterators.flatten(i.color for i in datas if i.color != nothing))
if !isempty(cdata)
cmin, cmax = extrema(cdata)
else
return
end

(cmin == Inf || cmax == -Inf) && return

if scale.minvalue != nothing
cmin = scale.minvalue
end
Expand Down Expand Up @@ -671,11 +658,11 @@ function apply_scale(scale::ContinuousColorScale,
end

function apply_scale_typed!(ds, field, scale::ContinuousColorScale,
cmin::Float64, cspan::Float64)
cmin, cspan)
for (i, d) in enumerate(field)
if isconcrete(d)
ds[i] = convert(RGB{Float32},
scale.f((convert(Float64, scale.trans.f(d)) - cmin) / cspan))
scale.f((scale.trans.f(d) - cmin) / cspan))
else
ds[i] = missing
end
Expand Down
4 changes: 2 additions & 2 deletions src/ticks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# little opaque because I want to avoid assuming the log function is defined
# over typeof(xspan)
function bounding_order_of_magnitude(xspan::DT) where DT
one_dt = convert(DT, one(DT))
one_dt = oneunit(DT)

a = 1
step = 1
Expand Down Expand Up @@ -69,7 +69,7 @@ function optimize_ticks_typed(x_min::T, x_max::T, extend_ticks,
granularity_weight::Float64, simplicity_weight::Float64,
coverage_weight::Float64, niceness_weight::Float64,
strict_span) where T
one_t = convert(T, one(T))
one_t = oneunit(T)
if x_max - x_min < eps()*one_t
R = typeof(1.0 * one_t)
return R[x_min], x_min - one_t, x_min + one_t
Expand Down
1 change: 1 addition & 0 deletions test/REQUIRE
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ DataFrames
RDatasets
Cairo
CSV
Unitful
3 changes: 2 additions & 1 deletion test/testscripts/percent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Gadfly

set_default_plot_size(6inch, 6inch)

import Base: show, +, -, /, *, isless, one, zero, isfinite
import Base: convert, show, +, -, /, *, isless, one, zero, isfinite

struct Percent
value::Float64
Expand All @@ -23,6 +23,7 @@ isless(a::Percent, b::Percent) = isless(a.value, b.value)
one(::Type{Percent}) = Percent(0.01)
zero(::Type{Percent}) = Percent(0.0)
isfinite(a::Percent) = isfinite(a.value)
convert(::Type{Float64}, x::Percent) = x.value
show(io::IO, p::Percent) = print(io, round(100 * p.value, digits=4), "%")

y=[Percent(0.1), Percent(0.2), Percent(0.3)]
Expand Down
19 changes: 19 additions & 0 deletions test/testscripts/unitful_basic.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Unitful, Gadfly, DataFrames

a = -9.81u"m/s^2"
t = (1:0.5:10)u"s"
v = a .* t
v2 = v .+ 2u"m/s"
h = 0.5 * a .* t.^2
df = DataFrame(time=t, velocity=v, position=h,
unitlesst=ustrip.(t), unitlessv=ustrip.(v), unitlessh=ustrip.(h),
position2=reverse(h))

# test basics of point/line plots with Unitful
gridstack(reshape([plot(df, x=:time, y=:velocity),
plot(df, x=:position, y=:time),
plot(df, x=:unitlesst, y=:velocity),
plot(df, x=:time, y=:unitlessh),
plot(df, x=:time, y=:position, Geom.line),
plot(df, layer(x=:time, y=:position, Geom.line),
layer(x=:time, y=:position2))], (3,2)))
15 changes: 15 additions & 0 deletions test/testscripts/unitful_color.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Unitful, Gadfly, DataFrames

a = -9.81u"m/s^2"
t = (1:0.5:10)u"s"
v = a .* t
v2 = v .+ 2u"m/s"
h = 0.5 * a .* t.^2
df = DataFrame(time=t, velocity=v, position=h,
unitlesst=ustrip.(t), unitlessv=ustrip.(v), unitlessh=ustrip.(h),
position2=reverse(h))

# Test that it's possible to categorize by Unitful quantities
vstack(plot(df, x=:time, y=:position, color=:velocity, Geom.point),
plot(df, x=:time, y=:velocity, color=:position, Geom.line),
plot(df, x=:time, y=:position, color=:unitlessv))
26 changes: 26 additions & 0 deletions test/testscripts/unitful_geoms.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Unitful, Gadfly, DataFrames

a = -9.81u"m/s^2"
t = (1:0.5:10)u"s"
v = a .* t
v2 = v .+ 2u"m/s"
h = 0.5 * a .* t.^2
df = DataFrame(time=t, velocity=v, position=h,
unitlesst=ustrip.(t), unitlessv=ustrip.(v), unitlessh=ustrip.(h),
position2=reverse(h))

# Test various geometries with Unitful
p1 = plot(df, x=:time, y=:velocity, Geom.bar)
p2 = plot(df, x=:time, y=:position, Geom.point,
intercept=[-80u"m"], slope=[10u"m/s"], Geom.abline)
p3 = plot(df, x=:time, y=:velocity, Geom.line,
yintercept=[-20u"m/s", -40u"m/s"], Geom.hline)
# Currently explicitly stated that it loess and lm require arrays of plain numbers
#p4 = plot(df, x=:time, y=:position, Geom.point,
# Geom.smooth(method=:loess, smoothing=0.2))
p4 = plot(df, x=:position, y=:velocity, Geom.path)
p5 = plot(df, x=:time, y=:position, Geom.step,
xintercept=[3u"s", 8u"s"], Geom.vline)
p6 = plot(df, layer(x=:time, y=:position, Geom.line),
layer(x=:time, y=:position2, Geom.bar))
gridstack(reshape([p1,p2,p3,p4,p5,p6], (2,3)))

0 comments on commit 2dfff47

Please sign in to comment.