cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Browse apps to extend the software in the new JMP Marketplace
Choose Language Hide Translation Bar

Scripters Club Recording: Running Python Code within JSL

Presenters: @martindemel and @jthi 

You may also want to watch the recording from West Coast Scripter's Club session on Python integration in JMP 18 from Paul Nelson 

5 REPLIES 5
Ressel
Level VI

Re: Scripters Club Recording: Running Python Code within JSL

Another dizzying session - so many more amazing things to learn!

Will the script that @jthi used for the on screen demos be shared?

Re: Scripters Club Recording: Running Python Code within JSL

yes, Jarmo will add the files here soon

/****NeverStopLearning****/
jthi
Super User

Re: Scripters Club Recording: Running Python Code within JSL

@Ressel just added the files!

-Jarmo
Georg
Level VII

Re: Scripters Club Recording: Running Python Code within JSL

great presentation, thanks for preparing the stuff and sharing!

Georg
jthi
Super User

Re: Scripters Club Recording: Running Python Code within JSL

I have attached the files I used in my part of the session.

 

In addition I have added code for my dark theme I use for JMP's Python Script Editor. If you wish to use it be sure to understand how those themes work, I haven't had any issues (yet), this is old wish list item so I'm not sure if all the comments are relevant anymore https://community.jmp.com/t5/JMP-Wish-List/JSL-Text-Editor-Color-Themes/idi-p/56203/page/2. The "theme" is controlled  by JMPStyles.PFS file found from C:\Users\<username>\AppData\Roaming\JMP\JMP\18 (for windows)

jthi_1-1718879116015.png

Example of the theme:

jthi_0-1718879010166.png

 

Copy paste the theme from here and save it as JMPStyles.PFS (JMP Community doesn't support uploading .PFS files)

View more...
//*** Generated Text, Editing this incorrectly may risk not being able to start JMP ***
Styles(
	Dark(
		Python(
			Default Enabled(
				Foreground Color({248, 248, 242}),
				Background Color({12, 16, 33})
			),
			Default Disabled(),
			Comment(
				Foreground Color({117, 113, 94})
			),
			Comment Blocks(
				Foreground Color({117, 113, 94})
			),
			Number(
				Foreground Color({230, 219, 116})
			),
			String(
				Foreground Color({230, 219, 116})
			),
			Decorators(
				Foreground Color({230, 219, 116})
			),
			Quoted string(
				Foreground Color({230, 219, 116})
			),
			Triple Quotes(
				Foreground Color({230, 219, 116})
			),
			Triple Double Quotes(
				Foreground Color({230, 219, 116})
			),
			Keyword(
				Foreground Color({78, 201, 176})
			),
			Identifiers(
				Foreground Color({220, 220, 220})
			),
			Operators(
				Foreground Color({220, 220, 220})
			),
			Line Number(
				Foreground Color({220, 220, 220}),
				Background Color({12, 16, 33})
			),
			EOL(
				Foreground Color({220, 220, 220}),
				Background Color({12, 16, 33})
			),
			Brace Light(
				Foreground Color({204, 221, 255}),
				Background Color({14, 69, 131})
			),
			Bad Brace(
				Background Color({107, 4, 3}),
				Foreground Color({221, 221, 221})
			)
		)
	)
)


 

Few comments of my examples

The HDBSCAN demo I did does require JMP Pro due to using JMP's Multivariate Embedding platform.

Orange parts are for JMP and blue for Python

jthi_2-1718879272327.png

I'm mostly getting started with the Python integration in JMP so my Python code definitely isn't the cleanest one, but for a quick example it should be good to go.

I use Python Send() to send variables to Python side

 

Python Send(dt);
Python Send(cluster_cols);
Python Send(clustersize);
Python Send(samples);
Python Send(epsilon);

and then Python Submit() to run the code below

import hdbscan
import jmp
import numpy as np
import pandas as pd

df = pd.DataFrame()
for colname in cluster_cols:
	df[colname] = np.array(dt[colname])

clusterer = hdbscan.HDBSCAN(min_cluster_size=int(clustersize), min_samples=int(samples), cluster_selection_epsilon=epsilon)
cluster_labels = clusterer.fit_predict(df)

df['Clusters'] = cluster_labels
col = dt.new_column("CLUSTERS", jmp.DataType.Numeric, jmp.ModelingType.Nominal)
dt[col.name] = list(df.iloc[:,2])
new_col = col.name

del df

The example first runs dimension reduction (tsne or umap), hdbscan on created two columns, displays graph, sets table script to re-create plot, groups columns and sets HDBSCAN parameters to CLUSTERS note column properties

 

jthi_3-1718888978759.png

 

 

As Python Get Graphics() has been deprecated you have to figure out other ways to get images from Python to JMP. JMP's example show how you can do it by first saving the image and then using JMP's Open() to load the image to JMP. I did demonstrate how you can use python modules io and base64 to load the image to JMP

 

Names Default To Here(1);

Python Submit("\[
import base64
import io
import matplotlib.pyplot as plt

plt.clf()
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.draw()

my_iobytes = io.BytesIO()
plt.savefig(my_iobytes, format='png', bbox_inches='tight')
my_iobytes.seek(0)
base64data = base64.b64encode(my_iobytes.read()).decode()
]\");

img = Open(Char To Blob(Python Get(base64data), "base64"), "png");
nw = New Window("test", img);

 

Finally I want to note that there are many ways to perform the transformation between pandas dataframe and JMP datatable. You can for example do "direct" transform using .csv files, use list(df.iloc[:,2]) or df[col].values.tolist(). There are examples of all of these and I haven't yet made my self familiar with the different methods to be able to make recommendations what you should use.

-Jarmo