Choose Language Hide Translation Bar

What do you get when you combine a Marine Biologist, a Video Game, and JMP? (2020-US-45MP-543)

Level: Intermediate

 

John Powell, Principal Software Developer, SAS/JMP Division

 

Novel ideas often come from combining approaches used in totally different industries. The JMP Discovery Summit and the JMP User Community provide excellent ways to cross pollinate ideas from one industry to another. This talk originated from a marine biologist’s request on the JMP User Community to display many variables in a tight space. Techniques used in video games provide possible solutions. I’ll demonstrate how JMP’s customizable visualization capabilities rise to the occasion to make these potential solutions a reality. Another use of video game technology is the 3D scatterplot capability available in JMP. This approach requires powerful graphics capability commonly available on modern desktop computers. But what if you need to share these scatterplots on the web? The range of graphics power on devices people use to view web content varies greatly. So, we need to use techniques that work even on less powerful devices. Once again, the games industry offers a solution — particle systems! I’ll cover particle system basics and how to export 3D data to a 3D Scatterplot application I built using particle systems on the web.

 

 

Auto-generated transcript...

 

Speaker

Transcript

jopowe Hi, welcome to my talk.
The motivation for this talk was based on a discussion on the JMP User Community. Dr. Anderson Mayfield is a marine biologist at NOAA and University of Miami.
He studies health of reef corals. He presented at our special Earth Day episode of JMP On Air. And he's also presenting at this conference.
So in this JMP User Community post, he posted this picture here. And if you could see, it has all these graphics that are representing corals or coral reefs
and they're representing multiple pieces of data, all in one little graphic, which is kind of like a video game when you have player stats
and they're hovering around the player as they run around the scene. So now you probably get an idea why I called my talk, you know, What Do You Get When Uou Combine a Video Game, a Marine Biologist and JMP? So let's move on.
What I'm going to talk about is this game based, or game inspired solutions that are possible in JMP, including using custom graphics scripts,
custom maps. And then I'm going to talk about a 3D web based scatter plot application that I built and how I integrated JMP data sets into that application.
Here's an example of the graphic script.
And here's an example of using custom maps. And here's my 3D scatter plot application.
So let's get started. To see how custom graphics scripts are used, I've got a little sample here.
And when I open up JMP and run
this little graphic, and actually, I'll talk about this.
I use this fictitious data set I created from scratch. And it's basically about a race of fish going all the way down from the Great Barrier Reef down to Sydney.
So to get to a graphic scripts, what you can do is go to customize.
And then this little plus button lets you add a new script. It starts off empty, but we've got a few samples in JMP.
So I like the polygon script. It's very simple. All it is, is it draws a triangle. So if I apply that to my graph, you can see a triangle in there.
And all it took us a three lines, setting the transparency, setting a fill color, and then drawing the polygon.
But what we're after is, how do you actually embed this in a script? So the easiest way to see that is you hit the answer button
and you save script to the script window. And here's the script. It starts off, there's my little bivariate platform being launched with latitude and longitude. And down below, there's a dispatch that has an add graphic script.
And then the three lines of the sample.
So there's a real simple example of using a graphic script.
Now this is a graphic script I'm going to embed. It draws these bars floating over each point.
And what I do first in this application, I set the transparency also and then I draw a background of my little graphic.
one for the hunger, one for the strength, and one for the speed.
Now I'm going to show you the whole script, because it relies on other things. It relies on these constants that I set up mostly for doing colors and in the background and a few things like the background like.
This is my function draw bar. It takes a position, a length and a color. So that can be used for each bar. So if I run that script.
There it is, you've got the graphic with the little
kind of game-inspired health monitors hovering above each fish as they swim down and race down the east Australian current to Sydney.
This is going to give you an idea, basically a step by step of how that function works. We started with just a marker on screen, and for each marker, we set the pixel origin.
And then we start to draw the background, but that takes a few steps. The first time we set the line thickness, you don't actually see anything.
Then we set the color, which is going to be black. And then we do a move to and line to that draws the background and very thick line.
And for each bar, we're going to set the color of the bar, move to the position and then do a line to. Then we draw the background, we set its color and it continues the bar. And of course we do that for the other two lines as well.
Now you can use many different graphics functions. And here's the graphic functions section of the JSL syntax reference and you can build whatever you want. So go at it.
Next, I'm going to talk about using custom maps.
Excuse me.
And to use custom maps, basically you provide two tables. The first table is a definition of all the shapes you want to use. And the second one names the shapes in the table.
And for this name column, basically what you need to add is a map role column property, and it needs to be of the type shape name definition. I'll show you that in a minute.
So just to do a real simple example, of course, what we need is Big Class. And I'm going to have a real simple.
map for it as well that just has two rectangles. Let me get those files open.
So it's very tiny map, as I said. And just to show you these coordinates, I've got a little
script here that basically shows the points.
If I highlight these top four, that's the top rectangle and the next four is the bottom rectangle.
the top ones is weight, the bottom one is height. And if you look at the column property,
it's map role, shape name definition.
So once we have this map ready, we can open up Big Class.
We can't reuse it directly. What we need to do first is take the height and weight columns and stack them. So we go to tables. Let me stack them.
And now I've got a table that has these columns stacked.
You see that the label has height, weight alternating, and what we need to do in order to hook that up to the map file is add another column property.
This one is all the way down here, map role again. But we won't say shaped name definition, we'll say shaped name use and we need to choose the
map file, the name map file.
And also set the column to name.
And then we're done. So now that we have that, I can actually use that in a graph.
The graph we're going after is basically using the label column for the map shape, which sets up the top and bottom shapes, and then we can drag in that data column that has all the data
into the color role. And there we have it, this is a summary of all of the students in Big Class, but we really want to get
one per student. If I drag that to the wrap role, it's a little tight, but I'm going to spread it out by doing a levels per row and set that to 10.
There we go. And that's pretty much what I was going after. And this can be useful graph
on its own.
So let's do something a little bit more complicated now.
Well, actually, if you're doing something more complicated, you might want to use the custom map creator add in.
And this is a great add in. It allows you to drag in an image and then trace over it.
And when you're finished tracing over all the shapes, you click on Finish with random data, and it will generate
the two shape files you need, as well as a random data set that allows you to test your custom map. And here's one where I just did four variables and one in the center. So it's basically a square version of what you saw in the original slide that I had.
Now that wasn't exactly what we're shooting for. We wanted something round, and I believe it was Dr Mayfield that called it complex pie.
I don't know if that's an official term but I decided I was going to build these things with script.
So what I wanted to do is build shape files and make sure that I got what the doctor ordered. And that was four shapes with something in the center.
And then I thought, Well, I'm a programmer. I like to do a little bit more and make a little more flexible.
So I thought maybe some people would want to do the same thing, but only have two variables plus an average or center variable or more.
And I thought maybe it would be nice to be able to also do different shapes like a diamond or square. So, I'm no genius. I got lucky. And Xan Gregg actually answered a post that was how can I make this polar plot in JMP.
And here it comes.
There we go and
They were looking for a shape like this, which was looks an awful lot like what I needed.
What Xan did was really great. It's a flexible script that does this, and generates these wedges around a circle, but the only thing missing was the center and also naming of files in a particular way that I wanted to do.
But it wasn't too difficult. And that is what my script does. And when you run complex pie, there's the recipe for this pie, you open the complex pie maker. Then you add some ingredients. First of all, you need to say the number of shapes.
And then whether you're going to center it, either at the top or off to the side a little bit.
Then there's a variable for smoothness.
And then you would want to also supply the inner radius, whether you want more filling or less, and the outer radius.
Of course, the next step is to run the script and it will generate
these
shape files for you and also do an example test, just like the custom pie maker or custom map add in. So here's an example of complex pie for five and shapes is five
and the smoothness to set to seven. You could use five or six and that would probably still be okay if they're going to be
drawn really small. The size doesn't really matter. It's more the relative inner radius and outer radius that matter. And this is approximately what Dr Mayfield was going with, so I stuck with four for the inner radius and nine for the outer radius.
So let's see how we can actually use these things. Just like we did with the Big Class demo, we're going to have to...we're gonna have to stack the columns. But one thing different is that I don't really have the strength and health variables in my shape file. They're actually
in the shape file, they're named wedge 1, 2 3 and
center.
So I'm going to need to build a
file that will
link the two together.
So first, I've got this stacked small school example,
which I did by stacking those health, strengths, speed columns together.
And here's the shape file that...the name shape file that I'm going to use.
Notice that it has a column property
of map role,
right, map role definition.
And that's required when you make your own custom shapes.
So the linked file, the maps columns to shape, I built basically by listing the labels within within my
stacked file.
And then in another column, shape name, I listed the shapes the shape names.
Now, it's important that the shape name here
have a property that is map role, but this one is shape name use.
And this data label column will have a link ID so it can be virtually joined back to my stacked table.
So now that I have these tables all set up,
the next thing to do is actually build a graph.
Now, it'll be similar to what I did before. The one difference is that instead of just dragging label down to map shape, now I use this virtually join column, drag that down into map shape and there's the shape I want. What I need to do next is add the data to the color column.
And then add name to wrap. And there are all my fish with
a graphic for each one. To try to get the right gradient, I go to gradient here and that is this one right here.
I want to make sure that the green is good, so I'm going to reverse the colors.
And there we have it. This is the
useful map on itself, because you can look at each fish and see how they're doing. But I want to do a little bit more with that, of course.
What I want to do is be able to put those images into a tool tip.
In order to do that, we're going to do make into data table.
Bring back the file that I had and that graphic.
So what it'll do here is, under the red triangle men there is a making to data table. And what this will do will produce a new data table
with all these images, and that's really useful, especially if we link it back. And I would turn this and set it as a link ID so that I can point to it from my my simple small school file so that I'll be able to have each marker, find the graph for each character.
Alright, so I've got this actually stored in another file and I'm going to open that one. I called it health images.
So we don't need this anymore.
And we don't need the stacked file anymore.
But what we do need is the small school example that I started with.
Now the first thing you need to do in order to get these to show up in the
graph is to set that image column, that virtual column,
as labeled.
You can do this in a simple graph as well.
So we already have an example...well, I'm going to open this again. Why not? My race script, just to show you that I'm starting from scratch. But since I've had this column labeled, now when I hover over one of these graphics, you get a...the three
pieces of information for this graphic and you can do that and pin any number of these characters.
So that's one way you can use these graphics.
Another way is to use use for marker.
And the graphics that you're going to get will be floating over the points and be used instead of the diamond shapes that I had before.
I'll bring back those health images, small school, and I'll even bring back that graphic.
So right now, we've got those diamonds. In order to turn them into these shapes over here,
we had to add yet another
badge to this virtual join column. It's really getting popular so use for marker. And so there's new badge that shows up. And behind me,
you'll see that these images were put in the scene. One last detail is I don't really like this white around the image. And that's actually built into the graph image.
And one way I can take care of that is, it's got a script that will find that white area and set the alpha channel so that it will make them transparent. So now we have graphs with a nice
round shape, not the square background. One other thing you might want to do is increase the marker size.
And we can go up to 11.
How does that look? That's pretty much looks like what I had; 10 would probably would have been better. But I like going to 11. Okay, so that's
use from marker. We want to make a little more complicated graph. And this is what Dr. Anderson Mayfield was going for, is a heat map behind the markers. And that's pretty complicated but JMP can handle that. That's actually a contour.
So one thing I have here is another version of small school. But this time, I've got ocean temperatures
down at the bottom
and they're hidden so that they won't show up as actual points.
So I've already built images for this one.
The same images, actually, as I built before.
And I'll start with
the end here so we can actually see what I'm going for. So I basically want to have these graphics
hovering over the contour and a couple of legends here that show what things are.
That shouldn't be too hard. I'll start part of the way with a map already placed in, and lat longs already on the x and y.
So the first thing I want to do is add in a contour.
And we need to give that little bit of color, so I'm dragging the temp role over the color role and I'm going to adjust the number of levels on this contour.
Change the alpha little bit and add some smoothness.
Next thing I want to do is make it a little transparent.
Let's put a .6 on that.
That's about the same as what I had before. And now to add the markers, there's two ways you can go about doing that. You can shift click on the points or you can just drag that in. To drag it in,
then you can set the marker size again,
doing that by
going to here and do other and let's use 10 this time. I think 11 was just a little too big. Alright, so that's looking good. That's almost there. We want to work on this legend. How do we get these colors in there? Well, we already have the health role.
And that you can drag right over here to the corner, just add a second color role. Kind of messes up your graph initially.
We can take care of that. The problem is that the contour doesn't really need to use the health role. So if we disable that then we're back to what we want.
So the next thing you want to do is add the color to the actual legend here. And we can just customize that again like we did before.
We're going to do a little bit more tis time. I want to have four labels.
I want to have it start at five and go up to
20.
Oh, I wanted to reverse the colors as well.
There we have it, looks pretty much like that, so almost done. I just want to pretty it up a little bit more. There's a couple of things in the legend I would like to fix up.
So go to legend settings and take away these things that don't seem to be adding too much and move the health legend up to the top.
There we have it. So I think I'm matching what I was going for, as good as I can.
So I can get rid of that one. I don't believe all need this anymore.
But I do want to add a little bit more so.
How about adding this legend, because it wasn't really a way to know which area of this graphic did what, you know hunger, speed, strength and health. Luckily we have that
mapping file. It goes from column name to shape.
And I'm just going to open that up for a second.
So you can see here that I've labeled all the rows and I labeled the data label column as well. That means that when you create a graph,
it will all be labeled. So this one's really simple. You just take the shape name and drag it into the map role and we're really done with that graphic.
So if I want to get that on to my scene, the best way to do that is to just select it, the plus sign and then copy it.
Then you open up some image editing application and save it to disk. And of course, I've done that already. So I'm going to
show once you have that, and I need to bring back my graphic again,
wow I can just drag this in.
And there it is. Oh, it's not there. Well, so there's a way to find it. Go to customize, it dropped it in the background because normally when you drag in an image, you're dragging in a background image.
So all we need to do now...let's move this out of the way so you can see what's happening...is move to the front. Here it comes
and there we go. It's at the front. And I'd like to actually add a little bit of transparency on this because a little too bright for my liking.
So let's put .8.
And now we just have to drag it into the corner and we're pretty much done with that.
Okay, so there was a lot and it involved a lot of files. So let's summarize all the files that were used. I used my complex pie maker to generate the two map files that are needed, shape files. I took small school and I stacked it.
I created this column to shape mapping file that needed to point to the name file with the map role. I used a link reference to do a virtual join back to small school stacked.
Then I made a graphic that I wanted to make into a data table and save that to my health images.jmp.
Of course, that had to be virtually joined back to the original small school so that I can make the graphic with that.
And then I did the same thing with small school ocean temps, my link reference to health images.
I only...I took my column to shape file and drew the legend for the graphic that I tried to do with the ocean temperatures and I used...I just use that by dragging it in basically.
So that's it for the 2D demonstrations I wanted to do. Let's take a little breather here and now we're going to go into the world of 3D, and even the web
application.
Okay.
So this is my web 3D scatter plot application.
And what I'm going to show you is how I got data from JMP into it.
My application was based on JMP's scatterplot 3D. So this is just to remind you how that looks.
And now I've got a little demo of that.
So basically, it had...I'm going to show you some of the features, starts off with the ability to select different data sets. Here's the diamonds data set.
And of course this drawing points. That's the whole idea. And they're drawn with this little ball shape which is I'll explain how that's done in a minute.
But the other things you can do is rotate it, just like in JMP, you can zoom, move it back and forth.
And then it has hover labels as well. You can see that bottom right corner I draw axes and a grid and add a little bit of customization. Not too much.
You can change the background, set the color of the walls. Let's see if we can give it a little blue color.
Yeah, maybe that's not to your liking. But this is just a demo. And then you can change the size of the markers.
That's up on the web.
Okay, so when I started this application, first thing I wanted to do is, could it perform on the web? Would it work well on my iPhone or my iPad?
Because those machines are not as powerful as my desktop. So I created built in 3D or three random data sets of increasing numbers of points. I went and used a...
25,000 was what I thought was worth trying on lower power devices, but you can go a lot higher actually with high powered devices.
Then I thought, well, I should try to bring some real data in and I found the famous iris data set, and it was in a CSV, comma separated variable, format.
And I brought it in. But I had to write some code just to convert it over to my internal structures.
And I thought, well JMP has a lot of data sets. I'd rather just bring those in. So I brought in cars, diamonds and cytometry. The only difference was cytometry, it didn't really have a good
category for using color and they actually had to change my application to accept a graph that didn't have any color.
So the application is pretty simple. There's only one...it's a one page web app. So there's one HTML file. I've got a couple of JavaScript files and i use a few third party libraries and one font and one texture, and the texture is the ball that is used for the shapes.
So the technique that I use from the games industry is particles or particle systems. They're used very commonly for simulation games and 3D visualization. You can do some cool effects like fire, smoke, fireworks, and clouds.
And I had spent some time working on a commercial game engine in the past and my responsibility was actually take the particle system and improve it.
So I did have some experience with this already. Um, that was in C++ world, not JavaScript. But since I worked on interactive HTML5 and JMP for quite a while, I thought it was time to see if I can take
two of my passions and marry them and come up with a web based version of using particle systems. I got lucky. I found this library, Three.js.
It does hardware accelerated 3D drawing and it has excellent documentation and there are many code examples including particle systems, so that made it quite easy to build my application.
And actually, the difficult part for me was figuring out how to get data into it from JMP.
But I will have...I'll share script for that. The one thing I did do is make sure that I made it easy to use these objects
in my application. So one thing that I did was I just created an array JavaScript objects and for the numeric columns actually add in a minimum and a maximum, so I don't have to calculate that in JavaScript. And of course, JMP is really good at calculating that kind of stuff.
Um, for the category, for the color column, what I needed to do is use like a category dictionary. And basically, all that is, the names of the categories in one list and then just point to those values by a zero based index. So that's how that structure works.
I thought it would be nice to do a user interface. And actually that was an easy thing to do. And I'll show you that in a second. But basically all I need to do is limit it to numerical columns for the x, y, and z.
And then limit it to a categorical column for the color role.
So let's have a look at that code.
Alright, so I give an example of a very simple data set first of all.
And then the dialogue really was easy to do. I use column dialogue and I specified what I wanted for the numeric columns and what I wanted for the color column, and made sure that the modeling type was categorical so its ordinal and nominal.
Next, I take the columns data and I build up the JavaScript objects that I need. Here's the min and max strings. And this is just building a string of these objects.
And then if there's a color column, I'll do the same. It's a little more complicated because I need to get those character strings out and stuff them into the JavaScript object.
And then finally, all it needs to do is save this to a text file.
So let's give this a shot.
Of course, I'm going to use Big Class, so it's a nice small file.
And
so I run the script.
And it asked me, What do I want for my XYZ. I've already got a height and weight selected and age is a numeric column, so I'll use that as well and sex is a good one for color.
And then we're done. And actually, the output here is telling me where the file is.
I happen to have that on the next slide. So let's go to that.
So I bet you always wondered what would Big Class looked like it was in JavaScript. And this is it. And so you can see the three
numerical columns with your min and the max, and then the color column has this dictionary of F and M for the categories, and the zero, it means female and the one means male. Well, that's my exciting finish to this talk, I hope you enjoyed it.
So thanks for watching, and if there are any questions, please ask them.