I made a 3D line plot Python add-in with matplotlib for ArcMap.
After I execute this tool 3-4 times, ArcMap crashed. I have also executed it in the Python window, but the situation is just the same.
Here is the code:
import arcpy
import pythonaddins
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
class ButtonClass1(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
# plot line
def plotWireframe(x,y,z,c):
ax.plot_wireframe(x,y,z,color=c)
mxd = arcpy.mapping.MapDocument("CURRENT")
arcpy.mapping.ListLayers(mxd)
layers = arcpy.mapping.ListLayers(mxd)
select_layers = [str(i.name) for i in layers if arcpy.Describe(i.name).fidSet]
numOfLayer = 0
for fc in select_layers:
if numOfLayer%3 == 0:
color = (0.1, 0.2, 0.5)
elif numOfLayer%2 == 0:
color = (0.5, 0.8, 0.5)
else:
color = (0.6, 0.2, 0.1)
numOfLayer = numOfLayer + 1
desc = arcpy.Describe(fc)
geometryType = desc.shapeType
if geometryType == 'Polyline':
for row in arcpy.da.SearchCursor(fc, ["SHAPE@"]):
for part in row[0]:
x = []
y = []
z = []
for pnt in part:
x.append(pnt.X)
y.append(pnt.Y)
if pnt.Z == None:
z.append(0)
else:
z.append(pnt.Z)
plotWireframe(x,y,z,color)
else:
print fc, "is not Polyline"
plt.show()
I guess the problem might caused by:
- Memory problem: but it happened even I only select one feature (polyline) to plot.
- The python GUI may not play well with ArcMap
The version information is as follows:
- ArcMap 10.2, 10.5 and 10.5.1 (both got the same crash)
- matplotlib version 1.5.2 (a build-in module in ArcGIS)
Has anyone using matplotlib in ArcMap encountered a similar problem?
1 Answer 1
I think, It's most probably about Python GUI (especially Tkinter). Matplotlib uses Tkinter by default. I couldn't figure it out why, but If I change GUI package for matplotlib to PyQt4, no more crashing with one exception.
First, I tried wxPython, but I encountered errors. Then I installed PyQt4 (cp27m‐win32) and after some editings on script like below, crashing stopped. (Three lines with #)
import arcpy
import pythonaddins
import matplotlib ##########
matplotlib.use("Qt4Agg") ##########
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
class ButtonClass1(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
# plot line
def plotWireframe(x,y,z,c):
ax.plot_wireframe(x,y,z,color=c)
mxd = arcpy.mapping.MapDocument("CURRENT")
arcpy.mapping.ListLayers(mxd)
layers = arcpy.mapping.ListLayers(mxd)
select_layers = [str(i.name) for i in layers if arcpy.Describe(i.name).fidSet]
numOfLayer = len(select_layers) ##########
for fc in select_layers:
if numOfLayer%3 == 0:
color = (0.1, 0.2, 0.5)
elif numOfLayer%2 == 0:
color = (0.5, 0.8, 0.5)
else:
color = (0.6, 0.2, 0.1)
desc = arcpy.Describe(fc)
geometryType = desc.shapeType
if geometryType == 'Polyline':
for row in arcpy.da.SearchCursor(fc, ["SHAPE@"]):
for part in row[0]:
x = []
y = []
z = []
for pnt in part:
x.append(pnt.X)
y.append(pnt.Y)
if pnt.Z == None:
z.append(0)
else:
z.append(pnt.Z)
plotWireframe(x,y,z,color)
else:
print fc, "is not Polyline"
plt.show()
However, there is one exception. If you hover mouse over the button while Figure window is open, ArcGIS crashes. Otherwise, everything is fine. (I used ArcGIS 10.5)
For more information about other GUIs for matplotlib, refer to table at the bottom of What is a backend? headline
-
I have tried this solution and it works great, I never thought we can change the default GUI, thank you @KadirŞahbaz.Kayson Cho– Kayson Cho2018年04月18日 10:27:28 +00:00Commented Apr 18, 2018 at 10:27
Explore related questions
See similar questions with these tags.
name 'numOfLayer' is not defined
.plt.show()
, no crashing.with arcpy.da.SearchCursor() as cursor:
syntax instead (sample code in its help).