Matplotlib Script Tool Geoprocessing Service Won't Show Plot

1555
5
02-08-2017 07:38 AM
LloydBronn
Occasional Contributor II

I have a Python script GP tool that creates a chart with matplotlib. A user can click on any point on a web map and generate a chart. I'm trying to figure out how to show the plot in a popup window on the web, much like plt.show() does if I run the script in IDLE. The problem is, plt.show() keeps the Python script running until the plot is closed, so it can't be run from the web. Right now I'm just saving the chart to our web server folder and then linking to it from an URL. I've tried adding a popup window for this link in Javascript, but nothing works. It always replaces the map and loads the chart on the same web page. I'm looking at the mpld3 plugin for matplotlib. Has anyone used this successfully? 

0 Kudos
5 Replies
NeilAyres
MVP Alum

We saved them into the env.scratchFolder which appears in the jobs directory on the server.

from arcpy import env
import matplotlib.pyplot as plt
pngDir = env.scratchFolder
pltPng = os.path.join(pngDir, pngName)
plt.savefig(pltPng, dpi=300)
plt.close()
msg = "Saved png {}".format(pngName)
arcpy.AddMessage(msg)

If you need the job id

jobID = env.scratchFolder.split("\\")[-2]

Let me know if you get them to add as popups.

I never quite cracked that. But used the path in the attribute table in another web page.

0 Kudos
LloydBronn
Occasional Contributor II

I had nothing but trouble trying to use the scratchfolder. The script kept looking for a local folder on the C:/ drive. It works saving them to our web root folder and then linking to the chart with an URL.

I just discovered that mpld3 won't work either. both plt.show() and mpld3.show() keep the Python script running in the background. 

I feel like there should be a solution in Javascript, but I haven't been able to find it. Window.open doesn't work. 

0 Kudos
NeilAyres
MVP Alum

May be I am misunderstanding you.

That's why we were using plt.saveFig.

show is interactive, if you were going to edit it or something. 

0 Kudos
LloydBronn
Occasional Contributor II

plt.show() keeps the Python script open and running while the plot is open. Since we're using the matplotlib script as a geoprocessing service over the web, It won't work because the Python script needs to complete for the tool to show results.  With plt.show() he window displaying the chart is a Python object, not an HTML object, so it won't display in the browser. 

Here is the solution we're using. We save the plot as a png to an URL accessible folder on our web server, and display the png in an iFrame in a new infoWindow. 

function gpResultAvailable(results, messages){
     domAttr.set(dom.byId("statsLink"),"innerHTML", "Three Week Chart");
     //clear any existing features displayed in the popup 
     window.map.infoWindow.clearFeatures();
 
     var content = "";
     if(results == 0){
          var chartPath = "http://<ourserver>/Test_Charts/Three_Week_Chart_for_" + locationStr + ".png";
          content = '<IMG SRC="' + chartPath + '" width=100% height=100%  position= middle/><br/><br/>';
          content = content + '<a target="_blank" href="' + chartPath + '">Right Click to Download Chart</a><br/>' + "for " + locationStr;
     }else{
          content = " Unable To Generate Chart";
     }
      window.map.infoWindow.resize(640, 660);
         window.map.infoWindow.setContent(content);
   
      
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
DanPatterson_Retired
MVP Emeritus

Check you conda distribution for ArcGIS PRO... My installation of conda may be different, but it includes 'bokeh' and there are others based on matplotlib.  I definitely have had the time to get drawn into the hole of web graphing, but if you 'have to' there must be ways to at least use the matplotlib design (plotly?)  Good luck

0 Kudos