python代码报错

AttributeError: 'OrientationViewer' object has no attribute 'image'达到的结果
代码如下:

from fipy import  CellVariable, Variable, ModularVariable, Grid2D, TransientTerm, DiffusionTerm, ImplicitSourceTerm, PowerLawConvectionTerm, MatplotlibViewer, Matplotlib2DGridViewer, MultiViewer
from fipy.tools import numerix
dx = dy = 0.025
if __name__ == "__main__":
    nx = ny = 200
else:
    nx = ny = 20
mesh = Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
dt = 5e-4
phase = CellVariable(name=r'$\phi$', mesh=mesh, hasOld=True)
dT = CellVariable(name=r'$\Delta T$', mesh=mesh, hasOld=True)
theta = ModularVariable(name=r'$\theta$', mesh=mesh, hasOld=True)
theta.value = -numerix.pi + 0.0001
DT = 2.25
q = Variable(0.)
T_0 = -0.1
heatEq = (TransientTerm(var=dT)
          == DiffusionTerm(coeff=DT, var=dT)
          + TransientTerm(var=phase)
          + q * T_0 - ImplicitSourceTerm(coeff=q, var=dT))
alpha = 0.015
c = 0.02
N = 4.
psi = theta.arithmeticFaceValue + numerix.arctan2(phase.faceGrad[1],
                                                  phase.faceGrad[0])
Phi = numerix.tan(N * psi / 2)
PhiSq = Phi**2
beta = (1. - PhiSq) / (1. + PhiSq)
DbetaDpsi = -N * 2 * Phi / (1 + PhiSq)
Ddia = (1.+ c * beta)
Doff = c * DbetaDpsi
I0 = Variable(value=((1, 0), (0, 1)))
I1 = Variable(value=((0, -1), (1, 0)))
D = alpha**2 * Ddia * (Ddia * I0 + Doff * I1)
tau_phase = 3e-4
kappa1 = 0.9
kappa2 = 20.
epsilon = 0.008
s = 0.01
thetaMag = theta.grad.mag
phaseEq = (TransientTerm(coeff=tau_phase, var=phase)
           == DiffusionTerm(coeff=D, var=phase)
           + ImplicitSourceTerm(coeff=((phase - 0.5 - kappa1 / numerix.pi * numerix.arctan(kappa2 * dT))
                                       * (1 - phase)
                                       - (2 * s + epsilon**2 * thetaMag) * thetaMag),
                                var=phase))
tau_theta = 3e-3
mu = 1e3
gamma = 1e3
thetaSmallValue = 1e-6
phaseMod = phase + ( phase < thetaSmallValue ) * thetaSmallValue
beta_theta = 1e5
expo = epsilon * beta_theta * theta.grad.mag
expo = (expo < 100.) * (expo - 100.) + 100.
Pfunc = 1. + numerix.exp(-expo) * (mu / epsilon - 1.)
gradMagTheta = theta.faceGrad.mag
eps = 1. / gamma / 10.
gradMagTheta += (gradMagTheta < eps) * eps
IGamma = (gradMagTheta > 1. / gamma) * (1 / gradMagTheta - gamma) + gamma
v_theta = phase.arithmeticFaceValue * (s * IGamma + epsilon**2)
D_theta = phase.arithmeticFaceValue**2 * (s * IGamma + epsilon**2)
thetaEq = (TransientTerm(coeff=tau_theta * phaseMod**2 * Pfunc, var=theta)
           == DiffusionTerm(coeff=D_theta, var=theta)
           + PowerLawConvectionTerm(coeff=v_theta * (theta.faceGrad - theta.faceGradNoMod), var=phase))
x, y = mesh.cellCenters
numSeeds = 10
numerix.random.seed(12345)
for Cx, Cy, orientation in numerix.random.random([numSeeds, 3]):
    radius = dx * 5.
    seed = ((x - Cx * nx * dx)**2 + (y - Cy * ny * dy)**2) < radius**2
    phase[seed] = 1.
    theta[seed] = numerix.pi * (2 * orientation - 1)
    dT.setValue(-0.5)
    from builtins import zip

    if __name__ == "__main__":
        try:
            class OrientationViewer(Matplotlib2DGridViewer):
                def __init__(self, phase, orientation, title=None, limits={}, **kwlimits):
                    self.phase = phase
                    Matplotlib2DGridViewer.__init__(self, vars=(orientation,), title=title,
                                                    limits=limits, colorbar=None, **kwlimits)

                    # make room for non-existent colorbar
                    # stolen from matplotlib.colorbar.make_axes
                    # https://github.com/matplotlib/matplotlib/blob
                    #   /ec1cd2567521c105a451ce15e06de10715f8b54d/lib
                    #   /matplotlib/colorbar.py#L838
                    fraction = 0.15
                    pb = self.axes.get_position(original=True).frozen()
                    pad = 0.05
                    x1 = 1.0 - fraction
                    pb1, pbx, pbcb = pb.splitx(x1 - pad, x1)
                    panchor = (1.0, 0.5)
                    self.axes.set_position(pb1)
                    self.axes.set_anchor(panchor)

                    # make the gnomon
                    fig = self.axes.get_figure()
                    self.gnomon = fig.add_axes([0.85, 0.425, 0.15, 0.15], polar=True)
                    self.gnomon.set_thetagrids([180, 270, 0, 90],
                                               [r"$\pm\pi$", r"$-\frac{\pi}{2}$", "$0$", r"$+\frac{\pi}{2}$"]
                                               )
                    self.gnomon.set_theta_zero_location("N")
                    self.gnomon.set_theta_direction(-1)
                    self.gnomon.set_rgrids([1.], [""])
                    N = 100
                    theta = numerix.arange(-numerix.pi, numerix.pi, 2 * numerix.pi / N)
                    radii = numerix.ones((N,))
                    bars = self.gnomon.bar(theta, radii, width=2 * numerix.pi / N, bottom=0.0)
                    colors = self._orientation_and_phase_to_rgb(orientation=numerix.array([theta]), phase=1.)
                    for c, t, bar in zip(colors[0], theta, bars):
                        bar.set_facecolor(c)
                        bar.set_edgecolor(c)

                def _reshape(self, var):
                    '''return values of var in an 2D array'''
                    return numerix.reshape(numerix.array(var),
                                           var.mesh.shape[::-1])[::-1]

                @staticmethod
                def _orientation_and_phase_to_rgb(orientation, phase):
                    from matplotlib import colors

                    hsv = numerix.empty(orientation.shape + (3,))
                    hsv[..., 0] = (orientation / numerix.pi + 1) / 2.
                    hsv[..., 1] = 1.
                    hsv[..., 2] = phase

                    return colors.hsv_to_rgb(hsv)

                @property
                def _data(self):
                    '''convert phase and orientation to rgb image array

                    orientation (-pi, pi) -> hue (0, 1)
                    phase (0, 1) -> value (0, 1)
                    '''
                    orientation = self._reshape(self.vars[0])
                    phase = self._reshape(self.phase)

                    return self._orientation_and_phase_to_rgb(orientation, phase)

                def _plot(self):
                    self.image.set_data(self._data)


            from matplotlib import pyplot

            pyplot.ion()
            w, h = pyplot.figaspect(1.)
            fig = pyplot.figure(figsize=(2 * w, h))
            timer = fig.text(0.1, 0.9, "t = %.3f" % 0, fontsize=18)

            viewer = MultiViewer(viewers=(MatplotlibViewer(vars=dT,
                                                           cmap=pyplot.cm.hot,
                                                           datamin=-0.5,
                                                           datamax=0.5,
                                                           axes=fig.add_subplot(121)),
                                          OrientationViewer(phase=phase,
                                                            orientation=theta,
                                                            title=theta.name,
                                                            axes=fig.add_subplot(122))))
        except ImportError:
            viewer = MultiViewer(viewers=(Viewer(vars=dT,
                                                 datamin=-0.5,
                                                 datamax=0.5),
                                          Viewer(vars=phase,
                                                 datamin=0.,
                                                 datamax=1.),
                                          Viewer(vars=theta,
                                                 datamin=-numerix.pi,
                                                 datamax=numerix.pi)))
        viewer.plot()
        eq = thetaEq & phaseEq & heatEq
        if __name__ == "__main__":
            total_time = 2.
        else:
            total_time = dt * 10
        elapsed = 0.
        save_interval = 0.002
        save_at = save_interval
        while elapsed < total_time:
            if elapsed > 0.3:
                q.value = 100
            phase.updateOld()
            dT.updateOld()
            theta.updateOld()
            eq.solve(dt=dt)
            elapsed += dt
            if __name__ == "__main__" and elapsed >= save_at:
                timer.set_text("t = %.3f" % elapsed)
                viewer.plot()
                save_at += save_interval

img

self.image没定义呀
你要先在init里设置self.image为你想要的类型,然后再在后面给它set值

OrientationViewer类没有image属性,所以报错了