将PatchCollection添加到matplotlib Axes3D时,Tkinter回调中的TypeError

时间:2017-06-25 16:10:21

标签: matplotlib tkinter

以下代码改编自Polygon示例here

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.collections import PolyCollection, PatchCollection
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import colors as mcolors

plt.ion()
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')


def cc(arg):
    return mcolors.to_rgba(arg, alpha=.6)

zs = range(4)
patch_list = []
for z in zs:
    patch = patches.Rectangle((0, 0), 10, 10, color=cc('r'))
    patch_list.append(patch)

patch_collection = PatchCollection(patch_list, match_original=True)
ax.add_collection3d(patch_collection, zs=zs, zdir='y')
ax.set_xlim3d(0, 10)
ax.set_ylim3d(-1, 4)
ax.set_zlim3d(0, 10)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

它适用于PolyCollection,但当我切换到PatchCollection时,我开始收到以下错误:

Exception in Tkinter callback Traceback (most recent call last):   
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1540, in __call__
        return self.func(*args)   
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 590, in callit
        func(*args)   
File "/home/csquires/.local/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 370, in idle_draw
        self.draw()   
File "/home/csquires/.local/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 351, in draw
        FigureCanvasAgg.draw(self)   
File "/home/csquires/.local/lib/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 464, in draw
        self.figure.draw(self.renderer)   
File "/home/csquires/.local/lib/python2.7/site-packages/matplotlib/artist.py", line 63, in draw_wrapper
        draw(artist, renderer, *args, **kwargs)   
File "/home/csquires/.local/lib/python2.7/site-packages/matplotlib/figure.py", line 1144, in draw
        renderer, self, dsu, self.suppressComposite)   
File "/home/csquires/.local/lib/python2.7/site-packages/matplotlib/image.py", line 139, in _draw_list_compositing_images
        a.draw(renderer)   
File "/home/csquires/.local/lib/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 271, in draw
        for col in self.collections]   
File "/home/csquires/.local/lib/python2.7/site-packages/mpl_toolkits/mplot3d/art3d.py", line 387, in do_3d_projection
        vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M)   
File "/home/csquires/.local/lib/python2.7/site-packages/mpl_toolkits/mplot3d/proj3d.py", line 207, in proj_transform_clip
        return proj_transform_vec_clip(vec, M)   
File "/home/csquires/.local/lib/python2.7/site-packages/mpl_toolkits/mplot3d/proj3d.py", line 164, in proj_transform_vec_clip
        vecw = np.dot(M, vec) TypeError: can't multiply

sequence by non-int of type 'float'

看起来它与后端有关 - 任何关于使用什么的建议?

2 个答案:

答案 0 :(得分:1)

您需要使用Patch3DCollection而不是PatchCollection。

使用以下内容导入Patch3dCollection:

from mpl_toolkits.mplot3d.art3d import Patch3DCollection

并将PatchCollection更改为Patch3dCollection,即

patch_collection = Patch3DCollection(patch_list, match_original=True)

答案 1 :(得分:0)

正如我对Jannick的评论中提到的,使用Patch3DCollection仍然给我带来了问题,而不是正确地将补丁附加到图表中。相反,我需要单独创建每个补丁,将其添加到轴,然后将其更改为3d:

zs = range(4)
colors = ['r', 'g', 'b', 'y']
for i, z in enumerate(zs):
    rect = patches.Rectangle(xy=(0, 0), width=10, height=10, color=cc(colors[i]))
    ax.add_patch(rect)
    art3d.patch_2d_to_3d(rect, z=z, zdir='y')