cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
] />

Discussions

Solve problems, and share tips and tricks with other JMP users.
Choose Language Hide Translation Bar
nozellot
Level II

Graph Box: values of variables continue changing even after creation

[JMP 19] In the following script, I am trying to create a series of graph boxes that are displayed below each other in a window. For this i am given a list of values for every important characteristic (these lists are all accessible via the Associative Array 'listMap'. Then I create all graph boxes via a for loop.
This however doesn't work because the variables that are used inside of the Graph Box (i.a. iVlistMap["median"][iV], numReferenceLines) also change the already created Graph Boxes that use them.

Is there a way to fixate the variables in a Graph Box? I want them to be evaluated instantly and then to not be able to be changed.
Disclaimer: According to my trials, 'Eval' doesn't seem to help. Neither do Namespaces (as they also still update, even if locked) or Journals (even if 'Freeze All' is activated).

Help of any kind is well appreciated. Thank you already in advance (:

ClearGlobals();
NamesDefaultToHere( 1 );

width = 1600;
height = 900;
boxPlotWidth = 0.5;
v = 3;

listMap = Associative Array();
listMap["frameHeightMin"]		= {0.5, 0.3, 0.4};
listMap["frameHeightMax"]		= {1.5, 2.0, 4.1};
listMap["numReferenceLines"]	= {3  , 5  , 8  };

listMap["min"]					= {0.6, 0.6, 0.5};
listMap["median"]				= {0.9, 1.4, 2.6};
listMap["max"]					= {1.3, 1.7, 3.9};

win = New Window("Test");
For(iV = 1, iV <= v, iV++,

	numReferenceLines	= listMap["numReferenceLines"][iV];
	frameHeightMin		= listMap["frameHeightMin"][iV];
	frameHeightMax		= listMap["frameHeightMax"][iV];
	
	win << Graph Box(
			Frame Size( width, height ),
			X Scale( 0, 2),
			Y Scale( frameHeightMin, frameHeightMax ),
			
			X Name("split"),
			Y Name("values"),
						
			//[] Generate grey horizontal lines
			For(h = 0,	h <= numReferenceLines, h++, HLine(frameHeightMin + (h/(numReferenceLines)*(frameHeightMax - frameHeightMin)))),
				
			//[] Min
			If(Contains(listMap, "min")		& Contains(listMap, "min"),
				Line({1 - boxPlotWidth/2,	listMap["min"][iV]	 },	{1 + boxPlotWidth/2,	listMap["min"][iV]		}));
			//[] Median
			If(Contains(listMap, "median")	& Contains(listMap, "median"),
				Line({1 - boxPlotWidth/2,	listMap["median"][iV]},	{1 + boxPlotWidth/2,	listMap["median"][iV]		}));
			//[] Max
			If(Contains(listMap, "max")		& Contains(listMap, "max"),
				Line({1 - boxPlotWidth/2,	listMap["max"][iV]	 },	{1 + boxPlotWidth/2,	listMap["max"][iV]		}));
	);
);
1 ACCEPTED SOLUTION

Accepted Solutions
jthi
Super User

Re: Graph Box: values of variables continue changing even after creation

Evaluate the values to your graph boxes using either EvalExpr() or Substitute() with Eval(). 

Names Default To Here(1);

width = 1600;
height = 900;
boxPlotWidth = 0.5;
v = 3;

listMap = Associative Array();
listMap["frameHeightMin"] = {0.5, 0.3, 0.4};
listMap["frameHeightMax"] = {1.5, 2.0, 4.1};
listMap["numReferenceLines"] = {3, 5, 8};

listMap["min"] = {0.6, 0.6, 0.5};
listMap["median"] = {0.9, 1.4, 2.6};
listMap["max"] = {1.3, 1.7, 3.9};

win = New Window("Test");

For(iV = 1, iV <= v, iV++, 
	numReferenceLines = listMap["numReferenceLines"][iV];
	frameHeightMin = listMap["frameHeightMin"][iV];
	frameHeightMax = listMap["frameHeightMax"][iV];
	
	Eval(EvalExpr(
		win << Append(Graph Box(
			Frame Size(width, height),
			X Scale(0, 2),
			Y Scale(frameHeightMin, frameHeightMax), 

			X Name("split"),
			Y Name("values"),

			Line({1 - Expr(boxPlotWidth) / 2, Expr(listMap["min"][iV])}, {1 + Expr(boxPlotWidth) / 2, Expr(listMap["min"][iV])});
		));
	));
);

Substitute is most likely better option for you, as you have so many variables to evaluate

-Jarmo

View solution in original post

3 REPLIES 3
jthi
Super User

Re: Graph Box: values of variables continue changing even after creation

Evaluate the values to your graph boxes using either EvalExpr() or Substitute() with Eval(). 

Names Default To Here(1);

width = 1600;
height = 900;
boxPlotWidth = 0.5;
v = 3;

listMap = Associative Array();
listMap["frameHeightMin"] = {0.5, 0.3, 0.4};
listMap["frameHeightMax"] = {1.5, 2.0, 4.1};
listMap["numReferenceLines"] = {3, 5, 8};

listMap["min"] = {0.6, 0.6, 0.5};
listMap["median"] = {0.9, 1.4, 2.6};
listMap["max"] = {1.3, 1.7, 3.9};

win = New Window("Test");

For(iV = 1, iV <= v, iV++, 
	numReferenceLines = listMap["numReferenceLines"][iV];
	frameHeightMin = listMap["frameHeightMin"][iV];
	frameHeightMax = listMap["frameHeightMax"][iV];
	
	Eval(EvalExpr(
		win << Append(Graph Box(
			Frame Size(width, height),
			X Scale(0, 2),
			Y Scale(frameHeightMin, frameHeightMax), 

			X Name("split"),
			Y Name("values"),

			Line({1 - Expr(boxPlotWidth) / 2, Expr(listMap["min"][iV])}, {1 + Expr(boxPlotWidth) / 2, Expr(listMap["min"][iV])});
		));
	));
);

Substitute is most likely better option for you, as you have so many variables to evaluate

-Jarmo
nozellot
Level II

Re: Graph Box: values of variables continue changing even after creation

Thank you a lot, this works fine for me. However, do you know if this is also somehow able to be implemented if I need a ForLoop inside of the "Graph Box(...)"? The following code is based on the previous example although it now contains multiple values per window for different boxplots.

Names Default To Here(1);

width = 1600;
height = 900;
boxPlotWidth = 0.5;
v = 3; // number of canvas'
n = 2; // number of boxplots per canvas

listMap = Associative Array();
listMap["frameHeightMin"] = {0.5, 0.3, 0.4};
listMap["frameHeightMax"] = {1.5, 2.0, 4.1};
listMap["numReferenceLines"] = {3, 5, 8};

listMap["min"] = {{0.7, 0.6}, {0.4, 0.6}, {0.7, 0.5}};
listMap["median"] = {{0.9, 0.9}, {1.3, 1.4}, {3.0, 2.6}};
listMap["max"] = {{1.4, 1.3}, {1.8, 1.7}, {3.8, 3.9}};

win = New Window("Test");

For(iV = 1, iV <= v, iV++, 
	numReferenceLines = listMap["numReferenceLines"][iV];
	frameHeightMin = listMap["frameHeightMin"][iV];
	frameHeightMax = listMap["frameHeightMax"][iV];
	
	Eval(EvalExpr(
		win << Append(Graph Box(
			Frame Size(width, height),
			X Scale(0, n + 1),
			Y Scale(frameHeightMin, frameHeightMax), 

			X Name("split"),
			Y Name("values"),
			For(iN = 1, iN <= n, iN++,
				Line({iN - Expr(boxPlotWidth) / 2, Expr(listMap["min"][iV][iN])}, {iN + Expr(boxPlotWidth) / 2, Expr(listMap["min"][iV][iN])});
				Line({iN - Expr(boxPlotWidth) / 2, Expr(listMap["median"][iV][iN])}, {iN + Expr(boxPlotWidth) / 2, Expr(listMap["median"][iV][iN])});
				Line({iN - Expr(boxPlotWidth) / 2, Expr(listMap["max"][iV][iN])}, {iN + Expr(boxPlotWidth) / 2, Expr(listMap["max"][iV][iN])});
			)
		));
	));
);

When trying to run this code, I always get the error "Name Unresolved: iN in access or evaluation of 'iN' , iN/*###*/Name Unresolved: iN in access or evaluation of 'iN' , iN/*###*/".
If you know more about how to do this, I would be very grateful (:

Btw., is there any website or forum post etc. to find out how Eval, EvalExpr and Expr actually work?

jthi
Super User

Re: Graph Box: values of variables continue changing even after creation

Usually I will evaluate the values inside GraphBox so they can be accessed easier, for example for For-loop. This .pdf, Scripting Guide, Scripting Index (within JMP) and JMP community are all quite good sources.

I would also suggest that you try to implement something much more simple when testing these things out to make them easier to understand

Names Default To Here(1);

width = 1600;
height = 900;
linecount = 3;
linesx = {1, 2, 3};
linesy = {4, 6, 8};

nw = New Window("",
	vlb = V List Box();
);

Eval(EvalExpr(
	vlb << Append(Graph Box(
		Frame Size(width, height),
		X Scale(0, 10),
		Y Scale(0, 10),
		X Name("split"),
		Y Name("values"),
		ngb = Expr(linecount);
		xs = Expr(linesx);
		ys = Expr(linesy);
		For(i = 1, i <= ngb, i++,
			H Line(xs[i]);
			V Line(ys[i]);
		);
	));
));
-Jarmo

Recommended Articles