# Can't force UnitConvert to be evaluated in Plot

I'm trying to use new units support in Mathematica 9.

When I Plot Quantity functions everything is OK.

v[e_] := Quantity[0.001, "m^3"] e
Plot[Evaluate@v[e], {e, 0, 1}]


But when I UnitConvert them, I get only an empty image with axes only.

v1[e_] := UnitConvert[v[e], "Liters"]
Plot[Evaluate@v1[n], {n, 0, 1}]


And no error message at all. By the way, Plot likes to do this very much - to draw nothing and not to tell why, and that sucks.

Other standard functions seem to be plottable even with Quantity arguments.

v2[e_] := Sqrt[v[e]]
Plot[Evaluate@v2[n], {n, 0, 1}]


I can't figure out, what is the difference. The only difference I see is a NumericFunction attribute.

In[84]:= Attributes[Sqrt]

Out[84]= {Listable, NumericFunction, Protected}

In[85]:= Attributes[UnitConvert]

Out[85]= {Listable, Protected}


But Quantity values aren't numeric themselves, so this shouldn't make difference, should it?

In[1]:= NumericQ[Quantity[1, "L"]]

Out[1]= False


Can anyone explain this, please? Or is it some kind of bug?

EDIT:

I think, I can answer this myself now.

As for Plot function, there is no sign in documentation and tutorials that using it with units supported. But there is also no sign that it isn't. Everywhere plotting with units is mentioned with different List*Plot functions. And they work fine with some good features:

v0[e_] := Quantity[0.001, "m^3"] e
es = Range[0, 1, 0.1];
cubes = v0 /@ es;
liters = UnitConvert[cubes, "L"];
ListLinePlot[cubes]
ListLinePlot[Transpose@{es, cubes}, AxesLabel -> Automatic]
ListLinePlot[Transpose@{es, liters}, AxesLabel -> Automatic]


or even

ListLinePlot[Transpose@{es, cubes}, AxesLabel -> Automatic, TargetUnits -> "Litres"]


It seems like Plot supports units, but "not very much". There is no TargetUnits parameter, and AxesLabel -> Automatic doesn't place unit names in labels. But still it can be used somehow. For my case, I found two solutions (thanks to @Anon for one of them and for direction to think to another).

This

Plot[Evaluate@UnitConvert[e Quantity[0.001, "Meters"^3], "L"], {e, 0, 1}]


doesn't work.

But this

Plot[Evaluate@UnitConvert[Quantity[0.001 e, "Meters"^3], "L"], {e, 0, 1}]


works. And this (a bit esoteric) variant too:

Plot[Evaluate@UnitConvert[Quantity[e, "m/m"] Quantity[0.001, "Meters"^3], "L"], {e, 0, 1}]


The reason for all these troubles may be the fact that Mathematica lacks a "truly" dimensionless units:

In[774]:= Clear[a]

In[775]:= QuantityUnit[a] (* this is OK, we don't know if 'a' has any \
units at all *)
Out[775]= QuantityUnit[a]

In[776]:= (* but we know that 1 doesn't have any *)
QuantityUnit[1]
Out[776]= "DimensionlessUnit"

In[777]:= (* and surely 1m has *)
QuantityUnit[Quantity[1, "m"]]
Out[777]= "Meters"

In[778]:= (* and this ratio is correctly dimensionless *)
QuantityUnit[Quantity[1, "m"]/Quantity[1, "m"]]
Out[778]= "DimensionlessUnit"

(* this ratio is dimensionless by its nature, but it isn't in Mathematica *)
QuantityUnit[Quantity[a, "m"]/Quantity[1, "m"]]
Out[779]= QuantityUnit[a]


The core of the problem seems to be here:

In[780]:= Quantity[Quantity[1, "m"], "m"]
Out[780]= Quantity[1, ("Meters")^2]


According to physics (and common sence) "1 meter of meters" is nonsense. No way it can be 1 square meter.

-
In my view you can find info being plotted using Table as Table[v1[e], {e, 1, 5}] and use a ListLinePlot as ListLinePlot[%]. This will give you the output. Another thing you can do is to convert head Quantityto List and print its [[1]] using ListLinePlot.Output shall be same in both cases. –  Rorschach Sep 15 '13 at 14:16
@Blackbird: ListLinePlot works fine without any additional conversions. But Plot might be shorter for typing and a bit more convenient, if it worked correctly. –  Anatol Sep 16 '13 at 3:10
PS To convert quantities to bare numbers QuantityMagnitude is better than [[1]] and works more often ;) –  Anatol Sep 16 '13 at 3:12
Anatol, your new examples with "L" instead of "Liters" don't work. Try UnitConvert[Quantity[0.001 , "Meters"^3], "L"] and it will tell you it does not recognize such a unit. –  Pickett Sep 16 '13 at 6:32
But they work for me. There is something unstable in the "online" unit recognition. And your code UnitConvert[Quantity[0.001 , "Meters"^3], "L"] work too. I've just made a screenshot with it, but can't upload it here. –  Anatol Sep 16 '13 at 7:02

v[e_] := Quantity[0.001, "m^3"] e


But defining it like this works:

v[e_] := Quantity[0.001 e, "m^3"]


And the reason I believe is the case where e=0:

UnitConvert[Quantity[0.001, "m^3"] 0, "Liters"]


Quantity::compat: 0. and Liters are incompatible units >>

When we put e inside we convert 0 cubic meters to liters, but when we put it outside we convert 0 - a unitless number - to liters, which is not possible.

This error should be fixed, one might think, by changing the lower boundary from zero to something else. This works if we calculate values of the function using Table. However that does not work with Plot.

-
Yes, this solves the problem, but it is not always possible (or convenient?) to place variables inside Quantities. –  Anatol Sep 16 '13 at 2:27
And about e=0 - it is a good note. But that's not the reason, because plot range {e, 0.1, 1} doesn't solve the problem. –  Anatol Sep 16 '13 at 2:28
@Anatol That's exactly what I said. But I edited it now, I no longer think precision has got anything to do with it. –  Pickett Sep 16 '13 at 6:27

First of all I get some errors while interpreting "m^3" so I used old safe "Meters"^3.

I have not much experience with Units in Mathematica so I don't know if they are supposed to work with plotting functions. Also I have not found such refferences in documentation (tutorial/UnitsOverview) so maybe they should no be trusted.

Those remarks are too long for the comment so I'm posting it here. Also, the natural workaround would be to use QuantityMagnitude.

v[e_] := Quantity[0.001 e, "Meters"^3]
v1[e_] := UnitConvert[v[e], "Liters"]

Plot[QuantityMagnitude[v1[e]], {e, 0, 1}, Evaluated -> True, PlotRange -> All]


I have also put e inside Quantity thanks to @Anon 's remarks.

-
When I look at Quantity[1, "m^3"] // FullForm it translates to Quantity[1,Power["Meters",3]] in V9, so it should be safe to use. Also, when I use something it cannot recognize it throws an error. –  Pickett Sep 15 '13 at 14:38
@Anon My pc is one big mess. So is the software, I have to reinstall all of it. I'm not surprised things are not working :p. What do you mean by "when I use something" –  Kuba Sep 15 '13 at 14:52
I meant that for examlpe Quantity[1, "fsfs"] returns "Quantity::unkunit: Unable to interpret unit specification fsfs. >>" so if it doesn't throw that error when you type "m^3" I think you can assume it's been correctly interpreted. –  Pickett Sep 15 '13 at 15:05

First seeing what values are you geting,

   Table[v1[e], {e, 1, 10}]


${1. L,2. L,3. L,4. L,5. L,6. L,7. L,8. L,9. L,10. L}$

Plotting these points,

Now another thing we can do is changing the Head from Quantity to List.

tab = Table[v1[e], {e, 1, 10}] ;
del = Abs[#[[1]]] & /@ tab /. Quantity -> List
ListLinePlot[del]


This second way of changing Head shows that M probably ignores the Head while processing or converts it.

-
When I execute the first line of code I get answers in "Liters", not "(km)^3". Also, I think it's intuitive that units don't matter how the values are being plotted. If I plot something in liters, I would implicitly assume that the axes would be in liters as well and not deciliters. Since the axes scale and the unit agrees, yes, heads don't matter. –  Pickett Sep 15 '13 at 14:46
@Anon Sorry I changed the Unit while experimenting. I checked now and graph stay same still.Just stays in +ive side. –  Rorschach Sep 15 '13 at 14:54
According to documentation, List-plots work with units without any troubles and with some features: v0[e_] := Quantity[0.001, "m^3"] e; es = Range[0, 1, 0.1]; cubes = v0 /@ es; liters = UnitConvert[cubes, "L"]; ListLinePlot[cubes] ListLinePlot[Transpose@{es, cubes}, AxesLabel -> Automatic] ListLinePlot[Transpose@{es, liters}, AxesLabel -> Automatic] ListLinePlot[Transpose@{es, cubes}, AxesLabel -> Automatic, TargetUnits -> "Litres"] - All these work correct. –  Anatol Sep 16 '13 at 2:17
Sorry for formating, can't do it in comments. –  Anatol Sep 16 '13 at 2:21
@Anatol : I have never read ListPlot` doc carefully.Thanks for informing me. –  Rorschach Sep 16 '13 at 9:56