3

maybe I'm completely newbie but I can't understand the behavior of units and the command plot.

I'm doing some easy plotting of the state equation for gasses:

R =  Quantity[0.0831, ("Bars" "Liters")/("Kelvins" "Moles")];
a =  Quantity[3.658, ("Liters")^2]* Quantity[1, ("Bars")/("Moles")^2]  
b = Quantity[0.0429, ("Liters")/("Moles")]
PVW[V_, T_, N_] := ((N*R*T)/(V - N*b)) - (+a*(N^2/V^2));

I then test that units are ok:

test = PVW[Quantity[0.6, "Liters"], Quantity[270, "Kelvins"], Quantity[1, "Moles"]];
UnitSimplify[test]

And I get my pressure back :

Quantity[30.1135, "Bars"]

Now I want my plot so I do :

Plot[PVW[V, Quantity[330, "Kelvins"], Quantity[1, "Moles"] ], {V, 
Quantity[0.06, "Liters"] , Quantity[0.6, "Liters"]},
Frame -> True, 
GridLines -> None,
LabelStyle -> {FontFamily -> "Helvetica", FontSize -> 15},
FrameLabel -> {"Volume", "Pressure"}]

If I evaluate that I get no errors, no nothing but a empty plot:

enter image description here

What is going on?

GIulio
  • 31
  • 3
  • Related: http://mathematica.stackexchange.com/questions/20867/plotting-with-units – Corey Kelly Jun 26 '13 at 14:12
  • -ish. (I tried that) He has an error when he plots in one way I don't (apparently, I don't know if there is an hidden trace somewhere), if I try the same solution suggested I still get the blank plot. – GIulio Jun 26 '13 at 15:24
  • In fact, I get an error when I attempt to evaluate your code as is. "Plot::pllim: "Range specification {0.06,0.6} is not of the form {x, xmin, xmax}. " " - Meaning that you need {V,Quantity[0.06, "Liters"], Quantity[0.6, "Liters"]}, but this doesn't improve things greatly. Unfortunately, I'm completely unfamiliar with Quantity[]. – Corey Kelly Jun 26 '13 at 15:41
  • Well, you've got at least one syntax error (but it doesn't solve the problem): you need {V,Quantity[0.06, "Liters"], Quantity[0.6, "Liters"]} as your plot limits, and you probably also don't want the curly braces around PVW call. – Andrew Jaffe Jun 26 '13 at 15:49
  • Yes there was a copy paste error in the code, I edited the code. – GIulio Jun 26 '13 at 15:53

2 Answers2

3

Still working out the why, but wrapping an Evaluate[] around your function seems to solve the problem:

Plot[
 Evaluate[
  PVW[V, Quantity[330, "Kelvins"], Quantity[1, "Moles"]
 ]
],
{V,Quantity[0.06, "Liters"],Quantity[0.6, "Liters"]}, 
Frame -> True, 
GridLines -> None, 
LabelStyle -> {FontFamily -> "Helvetica", FontSize -> 15}, 
FrameLabel -> {"Volume", "Pressure"}]

Plot

Edit:

This behaviour is discussed by Nasser in this related question.

Edit 2:

As mentioned in your comment, this problem is a little bit stranger than I'd realized. If anybody has insight as to why the following three examples return different results, feel free to chime in.

  1. As above, with Evaluate[] around the PVW[] call, and units passed via the plot range specification.

  2. Still using Evaluate[], but with the PlotRange[] being just numbers, and V being passed through a Quantity[] function:

    Remove["Global`*"];
    R = Quantity[0.0831, ("Bars" "Liters")/("Kelvins" "Moles")];
    a = Quantity[3.658, ("Liters")^2]*Quantity[1, ("Bars")/("Moles")^2];
    b = Quantity[0.0429, ("Liters")/("Moles")];
    PVW[V_, T_, N_] := ((N*R*T)/(V - N*b)) - (a*(N^2/V^2));
    Plot[Evaluate[
      PVW[Quantity[V, "Liter"], Quantity[330, "Kelvins"], 
       Quantity[1, "Moles"]]], {V, 0.06, 0.6}, Frame -> True, 
     GridLines -> None, 
     LabelStyle -> {FontFamily -> "Helvetica", FontSize -> 15}, 
     FrameLabel -> {"Volume", "Pressure"}]
    

    second plot

  3. Using numbers without units:

    Remove["Global`*"];
    R = 0.0831;
    a = 3.658;
    b = 0.0429;
    PVW[V_, T_, N_] := ((N*R*T)/(V - N*b)) - (a*(N^2/V^2));
    Plot[PVW[V, 330, 1], {V, 0.06, 0.6}, Frame -> True, GridLines -> None,
      LabelStyle -> {FontFamily -> "Helvetica", FontSize -> 15}, 
     FrameLabel -> {"Volume", "Pressure"}]
    

    third plot

Corey Kelly
  • 1,738
  • 9
  • 23
  • It works, but it seems that If now change say the tempeature inside the evaluate PVW call it doesn't change the plot – GIulio Jun 26 '13 at 15:57
  • Works for me: Show[Plot[ Evaluate[ PVW[V, Quantity[#, "Kelvins"], Quantity[1, "Moles"]]], {V, Quantity[0.06, "Liters"], Quantity[0.6, "Liters"]}, Frame -> True, GridLines -> None, LabelStyle -> {FontFamily -> "Helvetica", FontSize -> 15}, FrameLabel -> {"Volume", "Pressure"}] & /@ Range[50, 350, 50], PlotRange -> {{0.06, 0.6}, {0, 40000}}] – Corey Kelly Jun 26 '13 at 16:02
  • Yes, you are absolutely correct it works. But, I honestly didn't expect that output :D If i drop the units, I get the expected behavior! link EDIT:with the same paramters Temperature going from 250 to 350 in step of 10 – GIulio Jun 26 '13 at 16:10
  • Hmm. That's really odd. I can reproduce that here, too. – Corey Kelly Jun 26 '13 at 16:34
  • Didn't realize Quantity[] would convert units. Replacing "Bars" with "Pascals" makes my second two examples agree. I'm still not sure why the first one is different. I can't find any examples of passing Quantity[] values using the plot range. – Corey Kelly Jun 26 '13 at 18:46
  • Indeed, I found that one second ago too, but still I would expect to change it back to 'bars' with: TargetUnits -> "Bars". The first one is really strange though ! – GIulio Jun 26 '13 at 19:42
1

You need Evaluate to release the HoldAll (as mentioned here):

Plot[Evaluate@PVW[V, Quantity[330, "Kelvins"], Quantity[1, "Moles"]],
    {V, Quantity[0.06, "Liters"], Quantity[0.6, "Liters"]}, 
    Frame -> True, GridLines -> None, 
    LabelStyle -> {FontFamily -> "Helvetica", FontSize -> 15}, 
    FrameLabel -> {"Volume", "Pressure"}]

You also had a couple of typos (in an earlier version than current): you need {V,Quantity[0.06, "Liters"], Quantity[0.6, "Liters"]} as your plot limits, and you probably also don't want the curly braces around the PVW call.

Andrew Jaffe
  • 445
  • 3
  • 10