PainterQubits / UnitfulPlots.jl

Plots with unit labels, automatically
Other
9 stars 4 forks source link

Plotting a derived unit #2

Open barche opened 8 years ago

barche commented 8 years ago

Hi,

This package is a great idea, thanks. I tried plotting some derived units:

using Plots
using Unitful
using UnitfulPlots
using Unitful: Area, Pressure, m, Pa

x = Area[2m^2,3m^2]
y = Pressure[100Pa, 200Pa]

plot(x,y)

But this results in the error:

LoadError: MethodError: no method matching isless(::Float64, ::Unitful.Quantity{Int64,Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)},Unitful.Units{(Unitful.Unit{:Meter}(0,2//1),),Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)}}})
Closest candidates are:
  isless(::Float64, !Matched::Float64) at float.jl:283
  isless(::AbstractFloat, !Matched::AbstractFloat) at operators.jl:40
  isless(::Real, !Matched::AbstractFloat) at operators.jl:41
  ...
while loading In[2], in expression starting on line 9

 in expand_extrema!(::Plots.Extrema, ::Unitful.Quantity{Int64,Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)},Unitful.Units{(Unitful.Unit{:Meter}(0,2//1),),Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)}}}) at /home/myuser/.julia/v0.5/Plots/src/axes.jl:228
 in expand_extrema!(::Plots.Axis, ::Array{Unitful.DimensionedQuantity{Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)}},1}) at /home/myuser/.julia/v0.5/Plots/src/axes.jl:251
 in expand_extrema!(::Plots.Subplot{Plots.PyPlotBackend}, ::Dict{Symbol,Any}) at /home/myuser/.julia/v0.5/Plots/src/axes.jl:274
 in _expand_subplot_extrema(::Plots.Subplot{Plots.PyPlotBackend}, ::Dict{Symbol,Any}, ::Symbol) at /home/myuser/.julia/v0.5/Plots/src/pipeline.jl:354
 in _process_seriesrecipe(::Plots.Plot{Plots.PyPlotBackend}, ::Dict{Symbol,Any}) at /home/myuser/.julia/v0.5/Plots/src/pipeline.jl:384
 in _plot!(::Plots.Plot{Plots.PyPlotBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{Unitful.DimensionedQuantity{Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)}},1},Array{Unitful.DimensionedQuantity{Unitful.Dimensions{(Unitful.Dimension{:Length}(-1//1),Unitful.Dimension{:Mass}(1//1),Unitful.Dimension{:Time}(-2//1))}},1}}) at /home/myuser/.julia/v0.5/Plots/src/plot.jl:213
 in #plot#238(::Array{Any,1}, ::Function, ::Array{Unitful.DimensionedQuantity{Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)}},1}, ::Vararg{Any,N}) at /home/myuser/.julia/v0.5/Plots/src/plot.jl:52
 in plot(::Array{Unitful.DimensionedQuantity{Unitful.Dimensions{(Unitful.Dimension{:Length}(2//1),)}},1}, ::Array{Unitful.DimensionedQuantity{Unitful.Dimensions{(Unitful.Dimension{:Length}(-1//1),Unitful.Dimension{:Mass}(1//1),Unitful.Dimension{:Time}(-2//1))}},1}, ::Vararg{Array{Unitful.DimensionedQuantity{Unitful.Dimensions{(Unitful.Dimension{:Length}(-1//1),Unitful.Dimension{:Mass}(1//1),Unitful.Dimension{:Time}(-2//1))}},1},N}) at /home/myuser/.julia/v0.5/Plots/src/plot.jl:46
 in execute_request(::ZMQ.Socket, ::IJulia.Msg) at /home/myuser/.julia/v0.5/IJulia/src/execute_request.jl:169
 in eventloop(::ZMQ.Socket) at /home/myuser/.julia/v0.5/IJulia/src/eventloop.jl:8
 in (::IJulia.##9#15)() at ./task.jl:360

If I leave out the Area and Pressure it works.

ajkeller34 commented 8 years ago

Area and Pressure are abstract types, so you're actually making abstractly-typed arrays (Array{Area,1} objects). If you leave off the Area, you're letting Julia type the array. Unitful has some logic to figure out an appropriate concrete type for the array if you try to make an array with mixed units, but same dimensionality:

julia> [1.0u"μm", 1.0u"mm"]
2-element Array{Quantity{Float64, Dimensions:{𝐋}, Units:{m}},1}:
 1.0e-6 m
  0.001 m

That logic can be customized by the user if needed. Avoiding abstractly-typed arrays is important for performance reasons, see http://docs.julialang.org/en/release-0.5/manual/performance-tips/.

It would be nice if what you tried still worked or had an informative error message, I'll see what I can do when I have some time.

barche commented 8 years ago

OK, just to add some context as to why I tried this: It would be nice if the axes could be labeled automatically in this example as Area (m²) and Pressure (Pa). That way the unit does not have to be repeated at every number on the axes, reducing clutter. The ultimate reason I want this to work with derived quantities is so I can plot things like enhalpy and heat, which all have the same unit but different names. It would be awesome if just plot(s,T) would produce a correctly labeled T-s diagram.

ajkeller34 commented 8 years ago

Ah, I see. I think it could still be possible without the array being typed abstractly. I can work with dimension(eltype(A)) or something similar.