ANN: UnitfulRecipes.jl

UnitfulRecipes.jl is a tiny package, that makes plotting Unitful quantities more convenient:

using Unitful: cm, kg
using UnitfulRecipes
using Plots

xs = 1cm:1cm:10cm
ys = randn(10)*kg
plot(xs, ys)

img
It was inspired by the unregistered UnitfulPlots.

11 Likes

Does it work with unitful DiffEq outputs? that was the biggest problem with UnitfulPlots.jl

No idea. Can you give a MWE?

Sorry I’m not set up to do that right now, it was a while ago and the examples I do have are definately maximal. I remember discussing with @ChrisRackauckas somewhere but neither of us succeeded getting it working.

1 Like

Hmmmm… should this package be part of RecipesBase.jl or Plots.jl itself? We shouldn’t ask users to load a package just to plot with units IMO.

1 Like

Ok, here an example which semi-works:

using OrdinaryDiffEq
using Unitful: m, s
using Plots, UnitfulRecipes

const g = 9.81m/s^2
function traj2(u, p, t)
    x,y,vx,vy = u
    [vx,
    vy,
    0.0 * g, # make dimensionally consistent
    -g]
end

tspan = (0.0s, 30.0s)
u₀ = [0.0m, 0.0m, 100m/s, 100m/s]
sol = solve(ODEProblem(traj2, u₀, tspan), Tsit5())
plot(sol[1,:],sol[2,:]) # works
plot(sol) # does not work
#-> ERROR: DimensionError: m and m s^-1 are not dimensionally compatible.                                                                                                    
1 Like

I don’t think its a good idea for either Plots.jl or RecipesBase to depend on Unitful. I think the only reasonable candidate to include UnitfulRecipes would be Unitful.jl.

5 Likes

Where is the recipe for sol defined? Is the issue that it hands a matrix with mixed dimensions (m and m/s) to Plots?
Edit:

RecipesBase.apply_recipe(Dict{Symbol, Any}(),sol )[1].args[2]

shows that it indeed hands a matrix with mixed units over to plots. So producing a unitful plot from this is tricky.

1 Like

I think it’s here: https://github.com/JuliaDiffEq/DiffEqBase.jl/blob/master/src/solutions/solution_interface.jl

Maybe the simplest thing could be to do something equivalent to vars = (1, 2, ...) when the units are different? http://docs.juliadiffeq.org/latest/basics/plot.html#Choosing-Variables-1

This works:

julia> plot(sol, vars=[(0,1), (0,2)])

i.e. only plotting columns which have the same units.

The most elegant would be if the units were moved to the legend and the axis would not have any units. But that’s maybe more than @jw3126 signed up for.

Thanks for registering this, it’s just what I needed. I’ve been using UnitfulPlots for some debug plotting and loading it manually but it’s much better to have a registered package for this.

1 Like

At the moment I don’t need mixed units myself, so chances are low that I will implement it. PRs are appreciated though.