Choose Language Hide Translation Bar

I Can See It. How Do I Get It?

The most common use of the JMP Scripting Language is automating your work. Perhaps the second most common use is to extract results from JMP windows. It is easy to do, but unfortunately, it is not apparent to the uninitiated how to do it with a script. We explain the construction of windows with a unified model of display objects. We then present how to address any content in any window. Finally, we show several alternate forms of addresses.

We present the XPath query language, in particular. Rigorous background information is complemented by Illustrative and practical examples we developed while writing unit test scripts for JMP Development. We also highlight interactive JMP tools that make addressing JMP content more straightforward and accessible, as well as some best practices. Let us show you the best way to get what you want from your JMP results!

 

 

Hello. I'm Mark Bailey, I'm here with my colleague, Tanya Muldon. The title of our presentation is, I can see it, how do I get it? We're going to address a common situation. JMP produces lots of different results in different windows, and at some point, you might want to automate your analysis, you might want to customize, modify the display, or actually extract some information for further computation. This brings up several questions. How do I do that? Is there a mechanism to access these results? Is there a tool to help me? Finally, after nearly a quarter-century of JMP scripting, are there any best practices for this purpose?

Before I get into the main part of our presentation, I want to make a comment. You can ask JMP to save a script for your platform at any time. Any modifications that you've made to the display are automatically recorded using the Send to Display argument in the platform launch script. You would run this script in the future when you want to reproduce that analysis and the results.

This Send to Display argument is a mechanism that was invented to allow JMP to record these changes for you, but it was not intended for scripting. We're going to show you the techniques that are designed in JMP that are really best practices.

First of all, you need to understand that when you're looking at a window in JMP, you're really looking at two objects that are working together. The first object is called the analysis layer, and it's responsible for all the computations. You interact with the analysis layer through the contextual menus. For example, if you click a triangle to make a choice. The other object is known as the report layer, and it organizes and displays the results from the analysis layer.

You want to talk to the report layer. The way that we do this is through an object reference to which we can send a message. This report layer has a branched tree structure, and the reference that you start with is to the root of this display tree. The nodes along each of these branches are JMP display boxes. Now the question becomes, how do I locate or identify the display box to which I want to send a message? We do that with a subscript. The subscript is inside square brackets that follow the original report layer reference. It might be necessary to use more than one subscript if you have a heavily nested display box. These can be either successive subscripts or a single subscript with a list of the different boxes.

Your subscript can take several forms. It can be absolute, relative, or conditional. To illustrate this, I'm going to start a very simple example. Here, I open up the big REST data table. I send the message by variant to the data table to launch that analysis for weight versus height. Now that I have that reference saved in a variable object, I can send it messages. For example, I send the message fit line with the number 1 to enable that analysis, and you can see the result, the red least square's fit line.

But I'd like to select that box in which the plot is presented. I need to ask the analysis layer using the report message for a reference to it. I save that. Now I can subscript that reference, in this case, frame box one is the appropriate subscript. We'll get to that. Then I can send it the message, select. That's the basic way that we use subscripts.

Let's talk about absolute subscript first. In this case, you're using an index that tells you which fork to take as you're going through this branched structure of all these display boxes. Let's say that I'm interested in selecting that column of numbers in the summary of fit outline. I start with the root, the reference that was given to me, and I start walking down the branches. From that root, I go down the second branch, then the first branch, then the first branch, and so forth. Finally, I send the select method.

You can see that this works. Absolute scripts are valid and effective, but they're very difficult to specify and equally difficult to read. They're also bridal. By that, I mean they easily break depending on various circumstances, what you have open, the order in which you perform certain operations, and certainly updates to JMP itself. We don't recommend it.

The relative form is easier to specify and read. In this case, to get to that same column of numbers, I start with report, and then my subscripts are as follows. I want outline box number 3, table box number 1, number column box 1. You can almost picture what you're doing as you read this. The result is the same, but this is also less brittle.

The third way is to use the XPath query language. In this case, we send the XPath message to the report, and it takes a single argument. It's a character string that comprises the search string to get what we want. Again, the result is the same as the first two ways, but it's the least brittle. Moreover, it's the most powerful and flexible. It returns a list of all the matches, and it also is supported by many functions and conditional logic in this query language.

This slide shows you the beginning of the XML file for that bivariate window. This is the extensible markup language. We're not going to go into detail about it, but the idea is that this is a way of representing a JMP window, and the XPath query language is based on this form.

JMP display trees, any window in JMP, can be expressed using XML. XML in general is a way to tag and store hierarchical data and attributes. JMP implements version one of this language, and we have a separate handout that goes into more detail about the language and provides other online resources.

What I'd like to do now is go through a few of the basic syntax rules to give you an idea, and then I'm going to turn it over to Tanya to show you some real-world examples of how we use it.

XPath also has an absolute form or absolute path. It's indicated with a single slash, followed by the name of the node that you're trying to find. You show successive nodes using more slashes. But this is generally not the best way for JMP display trees, again, because JMP windows are dynamic.

A better way is the relative path. In this case, we use two forward slashes to identify the first node. That node can occur anywhere in the display tree, followed by additional nodes to finally search for the target that you want. They don't have to be adjacent, that is, successive branches.

In the third line, you see a simple example. The search string is for a relative path looking for outline box. This will return a list of all the nodes that are in an outline box, so it's very powerful. On the other hand, you could be more specific using a predicate, in this case, what's in the square brackets. I'll talk about those in more detail, but this allows us to qualify, we want not all outline boxes, but only outline boxes that have a title, summary of fit.

Along the same lines, we have wild cards, which allow us to specify some but not all of the details about a search. I want to look for an any outline box with a title that contains the word summary. The title could be the word summary, it could be a title like summary of fit. It'll find all matches. We can also use this to match all nodes at the next level. Outlinebox/* will return all of the display boxes within all of the outline boxes.

Similarly, we can not only search for nodes, but we can also search for attributes. In this case, we're looking for all of the attributes of all the outline boxes. The @ is the attribute symbol, and the asterisk says any of them.

Let's talk about predicates now a little bit more. Predicates are indicated in square brackets. In this case, we're looking for outline boxes that have a value, summary of fit. But we can do more. In the second line, you see the same search, except at the very end, we don't want all the number column boxes, we want the last one. You can indicate that type of information, such as in the third line, we want to search the first three outline boxes. We're using the position function, and it has to be less than the value for the match to for her. It can not only be something about the node, but it can be about an attribute with that node. We could look for all of the text edit boxes with a width greater than 10. You have this power available to you.

As you're searching through things, sometimes you want a reference to that display box, you want to send a message. But other times you want either the value or the attribute in that node. Here's an example. We're going to find all the access boxes, and for each of them, all the text edit boxes. Instead of returning a reference to the display box, we want the value, the current text in that box and so forth. The last line here we want to find out about the width of all of the outline boxes in the window.

Lastly, I just want to talk about XPath has this concept of axes, and axes is the same as what I mentioned earlier in terms of branching, going from one node to the next and what you find along the way, looking ahead or behind you or sideways. The first example here, I'm going to find all axes boxes, and then instead of specifying a certain type of node, the two periods indicate I want the parents of those axes boxes.

Same thing in the second line here, we're looking for number column box headers that have a header sum of squares, and then I want the parent node of that. That's the actual number column box. I can use explicit declarations about the relationship. In the third example here, I'm looking at the first picture box, and I'm looking for a child of type text edit box.

I can go the other way. This is similar to the second example on this slide. I'm looking for a number column box header of T-Ratio, and then I want to find a parent of that display box of type number column box. You have a lot of power, a lot of flexibility. Often a simple search string is adequate, but when necessary, you can use predicates and some of these other syntax tools that I mentioned.

JMP has some things to help you. If you go to the help menu and search scripting index, you can change this browser to show you display boxes, and you'll find all the display boxes that are available, all of their associated protocol, and it is searchable.

Also, if you right-click on the gray triangle in front of an outline box, you get a menu, and from there you can select Show Display Tree or Show Properties. These are interactive tools that help you explore the display tree and what the values and attributes are. That can be very helpful.

Also, the enhance log is a great way to see the results of your searches to see if you need to make any further modifications. There's a JSL message, Get XML. Sometimes you need to look at the underlying XML representation. It can be very helpful. Also, there's a JSL function, Get Display Path, and that tells you for a target display box, either the right subscript form or XML path form to refer to that box.

That's it for me. I'm now going to turn it over to Tanya for our live demonstration.

Thank you, Mark. This first case study that I want to take a look at, I want to use JSL to obtain the values found for me in this report. The first thing I need to do is determine what element holds these values. One way to determine that is via Show Properties.

Show Properties tells me that the mean values are contained it in a number column box. This panel right here shows the nested or branched tree structure that Mark discussed earlier. This number column box is part of the table box, which is part of an outline box, et cetera.

You'll also find this box Path outline node here. This right here is the JSL that you can use to obtain the reference to this number column box called mean. The default mode is the subscript method. You can also change this to XPath, and JMP will show you the XPath code to obtain a reference to that number column box called mean.

Once you've determined what element stores the information, you need to figure out what commands you can send to that element. One way of doing that is via the scripting index. When we look up number column box, we can find there are various get messages we can send to it. The one I'm going to use here is get as a matrix.

I'm going to use several different ways of obtaining this information. The first method I am going to send to my report. The RPT is my report layer that Mark discussed earlier. Within my report, I'm going to look for the first number column box, and I'm going to get those values as a matrix. I can see those values down here in my log. If I look back at my report, I can see they're the same values.

Next, I'm going to use an XPath command to get the same information. This time, I'm going to look for the outline box title, Variability Summary for Measurements. I'm going to look for the number column box that has the header mean, and I'm going to get that as a matrix.

Finally, I'm going to use some relative subscripting here. Within my report, I'm going to look for variability summary for measurement and the number column box called mean, and I'm going to get this as a matrix

Now, while I get the same results using all three methods here, this first method is one that we don't recommend. It is not very robust. If in the future, JMP were to change the report and add another number column box in front of me, then running this code would no longer give me the results that I expect to get.

These last two examples are pretty robust changes. The relative example that I showed last is shorter than the XPath example. That's normally going to be the case when you're only pulling out a single element from the report. Where XPath really shines is when you're pulling out more than one element at a time, or if you're doing something complicated with your wild cards and predicates, such as what Mark mentioned earlier.

Let's look at a more complicated example. In this case study, we want to pull out the limit summary information for both responses. We have two responses here, and we want the information from both. We can do that using the relative subscripting with two columns.

To our report layer, we can look for weight limit summaries in the first table box that appears underneath that, and we can get that information. We can then have a second command to look for weight to limit summaries in the first table box and get that information.

Alternatively, we can use a single X Graph command. In our report layer, we can look for the outline box titled Control Chart Builder. You see that up here. We can look for all table boxes that appear under Control Chart Builder, and we can get that information.

Writing that code, we see a lot more information in the log than expected. What you're seeing here are the table boxes that appear in your report, as well as invisible table boxes. There are other table boxes that are a part of this report, but we haven't added that information to our report layer yet, such as added limits or the Sigma report. We can add some information to our XPath statement for visibility.

For all of these table boxes, we want to look at the table box itself as well as its ancestors, and we want to look to see if they are visible or not. For this particular code, we're looking is the visibility false, but then we also have a not statement up here. In essence, what I'm really looking for are my table boxes that are visible in the report. When I run this, I now see that I get the same information that I got above with my two separate statements. XPath allowed me to gain this information via a single statement rather than two separate statements.

For this next case study, I am creating a prediction profiler and I have maximized desirability. I want to obtain the red Y values and the red X values that are in this report. Since they are both axis values and they're both red, you may think that they are stored within the same element. However, they are not.

We can see this by going back to our Show Properties window. If I can click on the right thing, there we go, we see that the Y values are actually text boxes, and the X values are number edit boxes. First, let's work with our text boxes. We're going to look for the prediction Profiler via XPath, and then we're going to look for our visible text boxes. Once again, we had to add some code for visibility because there are some text boxes that we cannot see in our report, and we do not want to get those.

Running that code, we see that not only are we getting the red values, but we're also getting these blue values for the confidence intervals, and that is because they are also stored as text boxes. We can add a for loop to cycle through each element and grab only the red values, every third one, and store this information in a matrix.

Now we have our Y values that were in red, but we also want our X values that were in red. These were stored in number edit boxes. We can use an XPath statement to look for a prediction profiler in the numbered edit boxes, and we want to get those values as a matrix. We have those values in our log down here.

For this next case study, I want to get all of the Y values for every line that is part of this first frame box or this location chart, the average diameter. When you look at Show Properties, you'll find that you can't really get into this frame box layer. When I click here, it shows me a frame box, but I can't see what's inside of the frame box. I need to know how these values are stored in my frame box. Another method of obtaining this information is using Show Tree Structure.

In Show Tree Structure, I can also see the branching structure that Mark talked about earlier. Within this frame box, I see that there are various segments. What I'm interested in are these line segments that appear down here. I can use an XPath statement to get all of the line segs from the first frame box.

Previously, all of my XPath statements have had an outline box node. This one does not. It's not really necessary in Control Chart Builder. All of the graphs in Control Chart Builder appear underneath this Control Chart Builder outline, even if you have multiple responses. Therefore, I don't really need it for this, it's not necessary.

If I run this, I see that there are seven elements. I can then choose to use an associative array to get those Y values from these elements. After running that, I see that my Y values for the added average are 4.2, my Y value for the added lower limit is 4.1, and so forth.

For this next case study, I have three different graphs. I want to make the Y axis for each of these graphs have the same minimum, maximum and add the same reference line to each graph. First, I need to obtain a handle to the axes box. I'm going to use XPath to look for the fit group outline node. Then I'm going to look for all axes boxes that are visible.

I see that I have six different axes boxes. There are three graphs, an X and a Y axis each, so that makes six. I'm going to use a for loop to cycle through each of these values. Only for the Y axis, I'm going to set the minimum to a value, the maximum to a value, and add a reference line. Now for each of my three graphs, I've added a reference line, and I've set the min the max to the same value.

For this next example, I want to shorten this overall Sigma Capability Summary Report. I only want to see what appears up to PP. I don't want to see CPM or these expected values or these observed values. I can do that via XPath. I'm going to send an outline box command to my report layer. I'm going to look for the overall Sigma Capability Summary Report.

After I have a reference to that level of the report, I want to use XPath to select header boxes that start with expected, or observed, or equal CPM. After I've selected those, I'm going to send the visibility collapse command. Now I see that those values have disappeared from my report. It's important not to delete items from your report. Deleting items from your report may have unexpected consequences. We suggest that you collapse or hide things in your report rather than deleting items.

I have one final example. For this case study, we have put the Manage Limits platform within a new window, and we want to get rid of this help button. When you create JSL scripts, you often do this because you want to share your results someone else. Therefore, you need to make sure your script is going to act the same on your computer as it does on somebody else's computer.

Windows and Macintosh often have buttons in different locations. You never want to look for a button based on a location in the report. You want to look for a button based on its name rather than its location. I'm not going to go into the with window handler code here, but what I want to draw your attention to is this XPath statement. I'm looking for the button box titled help, and then I'm collapsing the visibility. You'll see that the help button is no longer down here. Once again, I just hit it. I do not want to delete it from our report because I don't want to have unexpected consequences.

I've shown you three different methods of obtaining values from the report. The absolute subscripting is not a good method to use, it's not robust to changes. The XPath method and the relative subscripting are fairly robust. If you're just getting a single value from the report, the relative subscripting is probably a shorter code and simpler. The XPath code is useful when you're gathering more than one piece of information at a time, and if you want to do something complicated wild cards and such.

I hope that this information was helpful for you, and you're ready to go back and write some scripts.