Script Tool Fails when Adding a Legend

06-13-2018 07:57 AM
New Contributor II

I have a Python script that I'm using in a script tool in ArcToolbox. This script reads FAO food security indicator data and then plots the data for a country that the user chooses. When I run the script outside of ArcGIS, it plots the data with no issues.

However, when the script tool is run within ArcGIS, I receive an error the second time it is run. The error is:

"An error occurred: expected string or buffer"

The first time the script tool runs, everything works fine: it outputs a figure with food security information. It's the second time I run the tool that it fails and returns the above error.

A similar question was asked here: Arc Toolbox Python script tool plot legend error  

And ultimately the solution that was arrived at was to restart ArcGIS. When I restart ArcGIS, I am able to successfully run the tool again, but, as expected, it fails on the subsequent run. This will be inconvenient for the users of this tool since I don't want them to have to restart ArcGIS every time they run the tool for a different country or different food security indicator.

I've identified in the script where the issue occurs. I've imported matplotlib.pyplot as plt, and when my script includes 'plt.legend' in order to add a legend to the figure, this is what causes the script to fail on the second run. If I remove plt.legend from the script, I can run the tool as many times in succession as I want without an error (unfortunately, the plots that are created no longer have a legend).

Has anyone encountered this issue in the past? If so, have you found a way to overcome this without restarting ArcGIS every time?  

Here's my code where I add the legend:

plt.figure(figsize = (12, 9))

ax = plt.subplot(111)



ax.tick_params(axis = "both", labelsize = 10)

lineDrawType = [(5, 2, 20, 2), (2, 5), (4, 4, 2, 2), (4, 10), (5, 2)]

obsList = [iso_code, "lowestIncome", "midLowerIncome", "midUpperIncome", "uppermostIncome"]

labelObsNames = [countryName, "Low-Income", "Lower-Middle-Income", "Upper-Middle-Income", "High-Income"]

for rank, locationName in enumerate(obsList):

            df_plot = df_selected[df_selected["ISO_code"] == locationName]                                 

            plt.plot(df_plot["YearEnd"], df_plot["Value"], lw = 3., color = tableau[rank], ls = "--", dashes = lineDrawType[rank],             label = labelObsNames[rank])

artList = []

lgdPlotter = plt.legend(loc = "upper center", bbox_to_anchor = (0.5, -0.1), ncol=3)


plt.savefig(os.path.join(outputLocation, "test2.png"), additional_artists = artList, bbox_inches = "tight")


0 Kudos
3 Replies
MVP Emeritus

matplotlib doesn't play nice sometimes when arcmap is open.. it does behave somewhat better in PRO.

As in the other post, I don't use Catalog to run scripts or toolbox scripts.  

If I need to use matplotlib, I comment out plt.close() lines and manually close them when running a script from a toolbox... I don't know why but I suspect there is a small battle between the applications.

Running the scripts as a standalone is preferable and if you need an interface, qt is installed by default with PRO

New Contributor II

Thank you Dan,

Unfortunately, I need to include this as a script tool belonging to a larger suite of script tools that are shipped in an Arc Toolbox, so the users won't have the option to run as a standalone script. 

Since there seems to be this conflict between the applications, I might see if another library is able to plot my data without the conflict. 

Thank you, Paul

0 Kudos
MVP Emeritus

If you are using Pro, matplotlib will run.. as long as you don't get the script to close the graph which kindof can cause other problems.

There are others in the Anaconda suite installed with pro, depending on the type of graphing and the purpose of the graphing ie Orange – Data Mining Fruitful & Fun 

0 Kudos