# How do I properly use Quantities (units) in plots?

I'm having some problems making plots with quantities in Mathematica Online 11.3.0.

If I make a plot that is defined with the $x$-axis as an independent quantity (e.g., 0 to 3 seconds) and the $y$-axis as a dependent quantity (e.g., 0 to 100 meters, dependent on $x$), I get reasonable results. However, if I try to do unit conversions in my Plot call, I get an empty plot.

I suspect that I'm missing something about the evaluation order, but I'm not sure what. The question Can't force UnitConvert to be evaluated in Plot is related, but it's in the context of Mathematica 9. I'm using 11, and it seems that the way Plot handles units was changed significantly in 10; see https://www.wolfram.com/mathematica/new-in-10/enhanced-visualization/plot-functions-using-units.html

(By the way: I don't get the units next to my axes like that Wolfram post shows, and that's another matter.)

The following sample session demonstrates the problem I'm having. Here, I plot the descent of a ball dropped from a 100 m building. I demonstrate that it works fine when the $x$ and $y$ axes are Quantity objects, but if I make the Plot argument a UnitConvert expression, it's empty. Other things I tried are listed below.

In this example, s is the standard constant-acceleration equation, $s=a t^2 + v_0 t + s_0$, for freefall from a 100m tower, with $a = -9.8\ \frac{\text{m}}{\text{s}^2}$, $v_0=0\ \frac{\text{m}}{\text{s}}$, and $s_0 = 0\ \text{m}$.

(* Let s be the height of a ball dropped from a 100m tower, after t seconds. *)
In[1]:= s=Quantity[100,"Meters"]-Quantity[9.8,"Meters/Seconds^2"]*t^2
2
Out[1]= t  -9.8 meters per second squared + 100 meters

(* Test: Where is it after three seconds? *)
In[2]:= s/.t->Quantity[3,"Seconds"]
Out[2]= 11.8 meters

(* Test that UnitConvert can convert this to feet. *)
In[3]:= UnitConvert[s/.t->Quantity[3,"Seconds"],"Feet"]
Out[3]= 38.7139 feet

(* Plot the ball's path. This lets us confirm that Plot is able to use unit-based data on both axes. *)
In[4]:= Plot[s,{t,Quantity[0,"Seconds"],Quantity[3,"Seconds"]}]
Out[4]=


(* Plot the ball's path, but in feet. *)
In[5]:= Plot[UnitConvert[s,"Feet"],{t,Quantity[0,"Seconds"],Quantity[3,"Seconds"]}]
Out[5]=


I don't show it here, but the same thing happens if I try these:

• Use QuantityMagnitude[s, "Feet"] instead of UnitConvert[s, "Feet"]: i.e., try to do the conversion but into a scalar instead of a Quantity.
• Define s as a function instead; and plot UnitConvert[s[t], "Feet"].
• Define sf=UnitConvert[s,"Feet"] and plot sf.
• Plot Evaluate[UnitConvert[s,"Feet"].
• Set Evaluated->True in the Plot options.

Aside:

The original motivation for this, of course, wasn't this case. I was trying to plot (after substitutions) Plot[Sqrt[Quantity[5771, ("Milliamperes"*"Volts")/"Megahertz"] / l], {l, Quantity[1,"uH"], Quantity[22,"uH"]}]. However, the native units for this computation's result ($\frac{\sqrt{\text{mA}} \sqrt{\text{V}}} {\sqrt{\text{MHz}}\sqrt{\text{μH}}}$) are different from amps by a factor of $\frac{1}{10\sqrt{10}}$. So, I wanted to convert everything to milliamps to make it easier for me to deal with, but found out that doing the conversion gave me a blank plot.

UnitConvert can't evaluate, because s doesn't have well-defined units (what are the units of t?). So your issues nothing to do with updates to the visualization functions.

The following is probably your best approach: substitute in a dimensionalized t, and then plot with t dimensionless, like so

Plot[Evaluate@UnitConvert[s /. t -> Quantity[t, "Seconds"], "Feet"], {t, 0, 3}]

In principle, your solution should be the TargetUnits option, but it doesn't seem to work in Plot. I think the function plots (Plot, Plot3D, etc) are behind the data plots (ListPlot, ListPlot3D, ...) in automatic conversion because it is both implementationally harder, and there is a language issue: AxesLabel->Automatic alread meant something (show the independent variables) which can clashes with the new meaning of "show units". I'll do some digging and report back if I find anything useful to add.

• Thanks for the explanation. From your description and Bob’s example, I’m starting to get the impression that Plot will evaluate the function without substitution first, then break apart Quantity expressions to extract the magnitude function and unit separately, and only after that will it substitute in the independent variable. Since my function didn’t evaluate to something with a Quantity head (before t was substituted), then Plot just started plugging in values of t and didn’t have anything to do with the non-numeric results. This gives me some ideas of other experiments to try. Mar 23 '18 at 12:14
• You'd know the answer to this and could save me a lot of spelunking time: Can I access Mathematica streams from C through LibraryLink? I keep looking at WolframStreamsLibrary.h, but it seems that this is for implementing new stream types in C, and not for accessing existing streams. There's no example included so it's unclear. What I want: implement an importer for some file type in C (it has to be in C!), and have it work with all streams (especially pipes as in Import["!someprog", "MyFormat"]) Mar 24 '18 at 9:31
• Here's a question, where you could give some feedback ... mathematica.stackexchange.com/q/169705/12 Mar 24 '18 at 19:01
s = Quantity[100, "Meters"] - Quantity[9.8, "Meters/Seconds^2"]*t^2;

factor = QuantityMagnitude[Quantity[1, "Meters"], "Feet"];

Plot[s*factor, {t, Quantity[0, "Seconds"], Quantity[3, "Seconds"]}]


I wanted to briefly answer the side issue you had, ie. units not being displayed on your axes.

Turns out that you have to change the PlotTheme to "Web" (just like the example here shows) in order for the units to be displayed.

I have not experimented with other themes so PlotTheme -> "Web" might not be unique.

Edit: Turns out you also have to use FrameLabel -> Automatic although that might be obvious to most.

Using Itai Seggev's solution and my above comment you should get something like this: