Python3.6 / matplotlib:streamplot忽略xlim

时间:2017-03-29 01:49:32

标签: python matplotlib

以下代码生成一些图形文件。我的问题在最后。尽管有明确的ax.set_xlim(...)命令,但数字的变化范围为x。我想将这些数字用作电影中的帧,因此显示的非均匀范围是个问题。谢谢PN

"""
Description: MDantenna.py

Python 3.6
"""

import numpy as np 
import matplotlib.pyplot as plt
from scipy.integrate import quad
plt.close('all')

""" variables
zbar = observer position in units of b, the ring radius
ctbar = observation time, times speed of ligh in units of b
kbar = wavenumber in units of 1/b"""
# parameters
gridsize = 7. # spatial extent of the grid to examine
gridN = 73  # number of gridpoints is 2*gridN**2. Use a big value for final run like 300
numFrames = 3 # how many movie frames
file_name = "{:03d}_movie.jpg"

def Rfun(xbar_, zbar_, alphlist): return np.sqrt(xbar_**2-2*xbar_*np.cos(alphlist)+zbar_**2+1)
def integrand1(alpha, ctbar_, xbar, zbar, kbar_):
    R = Rfun(xbar, zbar, alpha)
    phase = kbar_*(ctbar_ - R)
    return((-np.cos(phase)/R + kbar_*np.sin(phase))/R**2)
def integrand2(alpha, ctbar_, xbar, zbar, kbar_):
    R = Rfun(xbar, zbar, alpha)
    phase = kbar_*(ctbar_ - R)
    return(np.cos(alpha)*(-np.cos(phase)/R + kbar_*np.sin(phase))/R**2)

fig=plt.figure()
kbar = 2.*np.pi/3. #0.0 # 0 gives the static case (kbar=omegabar in these units)
xvals = np.linspace(0.,gridsize,gridN); nX = len(xvals)
zvals = np.linspace(-gridsize, gridsize, 2*gridN); nZ = len(zvals)
Bx = np.zeros((nX,nZ)); Bz = np.zeros((nX,nZ))
X,Z = np.meshgrid(xvals,zvals,indexing='ij')
whichframe=0
for ctbar in np.linspace(0, 2*np.pi/kbar, numFrames):
    whichframe+=1; print(whichframe)
    for ix in range(nX):
        for iz in range(nZ):
            x = X[ix,iz]; z=Z[ix,iz]
            Btmp1, er = quad(integrand1,-np.pi,np.pi,args=(ctbar,x,z,kbar))
            Btmp2, er = quad(integrand2,-np.pi,np.pi,args=(ctbar,x,z,kbar))
            Bx[ix,iz] = -z*Btmp2
            Bz[ix,iz] = -Btmp1 + x*Btmp2
    ax = plt.axes(xlim=(0,gridsize),ylim=(-gridsize,gridsize))
    for xstart in np.arange(.9,.4*gridsize,0.44):
        mystarts=np.array([[xstart + ctbar, 0.]]) 
        ax.streamplot(xvals,zvals,Bx.T,Bz.T,arrowsize=.4,start_points=mystarts)
        ax.axis('equal'); 
        ax.set_xlim((0,gridsize))
        ax.set_ylim((-gridsize,gridsize))
    plt.savefig(file_name.format(whichframe))
    plt.cla()

1 个答案:

答案 0 :(得分:0)

有几件事可以帮助您的代码,但主要问题是行ax.axis('equal');不起作用。用ax.set_aspect('equal')替换它会得到您期望的结果。

除此之外,您将pylab - 样式命令与轴对象命令混合。我已经注释掉了一些不必要的行,并将其余部分更改为使用pylab样式。

这适用于Matplotlib 2.0:

#fig=plt.figure() <- This figure is never used, one will be created for you
kbar = 2.*np.pi/3. #0.0 # 0 gives the static case (kbar=omegabar in these units)
xvals = np.linspace(0.,gridsize,gridN); nX = len(xvals)
zvals = np.linspace(-gridsize, gridsize, 2*gridN); nZ = len(zvals)
Bx = np.zeros((nX,nZ)); Bz = np.zeros((nX,nZ))
X,Z = np.meshgrid(xvals,zvals,indexing='ij')
whichframe=0
for ctbar in np.linspace(0, 2*np.pi/kbar, numFrames):
    whichframe+=1; print(whichframe)
    for ix in range(nX):
        for iz in range(nZ):
            x = X[ix,iz]; z=Z[ix,iz]
            Btmp1, er = quad(integrand1,-np.pi,np.pi,args=(ctbar,x,z,kbar))
            Btmp2, er = quad(integrand2,-np.pi,np.pi,args=(ctbar,x,z,kbar))
            Bx[ix,iz] = -z*Btmp2
            Bz[ix,iz] = -Btmp1 + x*Btmp2
#    ax = plt.axes(xlim=(0,gridsize),ylim=(-gridsize,gridsize)) <- only one axis per plot and limits are set later, so not needed
    for xstart in np.arange(.9,.4*gridsize,0.44):
        mystarts=np.array([[xstart + ctbar, 0.]]) 
        plt.streamplot(xvals,zvals,Bx.T,Bz.T,arrowsize=.4,start_points=mystarts)
    # These lines only need to be called once before saving the figure, so move them out of the loop
#    plt.axis('equal'); <- this wasn't setting the axes to `equal`
    plt.axes().set_aspect('equal') 
    plt.xlim((0,gridsize))
    plt.ylim((-gridsize,gridsize))
    plt.savefig(file_name.format(whichframe))
    plt.clf() # clear the entire figure