使用循环

时间:2016-03-12 05:14:58

标签: python numpy matplotlib

在下面的代码中,我有一个循环,它将根据我的输入数据读取不同的文本文件,然后进行一些计算。我也在绘制一个依赖于时间的函数。所以如果循环的长度是5,那么我将在一个图中有5个不同的叠加。由于每条曲线都对应一个流动时间,因此我想在图形中使用适当的t1值对每条曲线进行注释,该值对于循环中的每次迭代都会发生变化。理想情况下,我希望有一条带箭头的线指向每条曲线并具有相应的注释。

我还想在图表中自动更新图例,即。图中的每条曲线应对应于t1的特定值。我已经看了一些例子,但我无法为我的问题找到任何工作。我请求SO社区帮助我。

在这个示例代码中,我提供了三个文本文件。因此,如果代码运行,它将生成3个叠加层。每个注释应对应于循环中计算的t1的唯一值。

更新1:我修改了代码,以便根据循环中计算的每个t1值更新图例。这是一个微不足道的修复。我仍然无法用t1的值注释每条曲线。

 # ... package imports ...
import numpy as np
from scipy.interpolate  import griddata
from matplotlib import pyplot as plt
from scipy import integrate
from scipy import interpolate
import math
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
from scipy.interpolate  import RectBivariateSpline
plt.ioff()

Uj = 0.944              
W = 30.48              
dj = 0.3048             
dj_length = (2*dj)      
Ho_bar = 44.607         
Ho_bar = (Ho_bar-(2*dj))
Ho = (Ho_bar*(1/W))
djo = 1.2192            
rho = 998              
D = W/W

path = "Location where the text files are located"
FT_init = 3.610
delt = 0.15
TS_init = 140

TS_init0 = 100

flowtime = np.linspace(50,2350,3)
timestep = ((flowtime-FT_init)/delt)+ TS_init
timestep = np.array(np.round(timestep,-2),dtype = 'int')

def Ekbar(KE_h,Y4):     
        plt.figure(1,figsize=(4.5,2.875))
        plt.plot(KE_h,Y4,label=(t1[s]))
        plt.ticklabel_format(style = 'sci', axis = 'x', scilimits=(0,0))
        plt.ylim(Y4.min(),Y4.max())
        plt.xlabel("X")
        plt.ylabel('Y')
        plt.tight_layout()

for s in range(len(timestep)):

        flowtime1 = flowtime
        flowtime1[s] = (timestep[s]-TS_init)*delt+FT_init 
        flowtime1[s] = np.array(np.round(flowtime[s]),dtype = 'int') 
        q = np.array(flowtime1)    
        timestepstring=str(timestep[s]).zfill(4)

        t = ((Uj*dj)/(W*W))*q           ## Nondimensional time
        t1 = np.round(t,decimals=2)
        fname = path+"ddn130AE-"+timestepstring+".txt"
        f10 = open(fname,'r')
        data = np.loadtxt(f10,skiprows=1)
        data = data[np.logical_not(data[:,11]== 0)]       

        data = data[data[:, 2].argsort()]
        Y  = data[:,2]          # Assigning Y to column 2 from the text file
        limitz = np.nonzero(Y==dj_length)[0][0]
        Vf = data[:,11]
        Vf = Vf[limitz:]
        Tr = data[:,9]          
        Tr = Tr[limitz:]       
        X  = data[:,1]        
        X = X[limitz:]        
        Y  = data[:,2]          
        Y = Y[limitz:]        
        U_bar  = data[:,3]      
        U_bar = U_bar[limitz:]        
        V_bar  = data[:,4]      
        V_bar = V_bar[limitz:] 
        U = (U_bar/Uj)         
        V = (V_bar/Uj) 
        limit = np.nonzero(Y==Y.max())[0][0]
        limit1 = np.nonzero(X==X.max())[0][0]
        Y1 = Y[limit]
        X1 = X[limit1]  

        nx = (5*(W/dj))
        ny = (5*(Y1/dj))
        pts = np.vstack((X, Y)).T
        U1 = np.vstack((U))
        V1 = np.vstack((V))
        # The new x and y coordinates for the grid
        x = np.linspace(X.min(), X.max(), nx)
        y = np.linspace(Y.min(), Y.max(), ny)
        r = np.meshgrid(y,x)[::-1]

        ipts = np.vstack(a.ravel() for a in r).T
        Uf = griddata(pts,U1,ipts,method='nearest')
        Vf = griddata(pts,V1,ipts,method='nearest')

        Uf1 = np.multiply(Uf,Uf)
        Vf1 = np.multiply(Vf,Vf)
        velsum = np.array(Uf1+Vf1)
        velsum = np.reshape(velsum,(len(x),len(y)))

        KE_int = interpolate.RectBivariateSpline(x,y,velsum)
        Sip1 = KE_int(x,y)

        axisx = np.linspace(0,D,num=len(Sip1))          
        KE_h = np.zeros(len(Sip1[0]))

        for i in range(len(Sip1[0])):
                KE_h[i] = integrate.simps(Sip1[:,i],axisx,axis=0)                

        KE_h1 = integrate.simps(Sip1,axisx,axis=0)

        Y4 = np.linspace(Y.min(),Y1,num=len(KE_h))   
        Y4 = Y4/W 
        Ekbar(KE_h,Y4)

plt.savefig('test.png',format = 'png', dpi=1200, bbox_inches='tight')    

Upload

1 个答案:

答案 0 :(得分:2)

我仍然认为这个问题应该通过一个小的示例代码进行简化。

要添加注释,您需要知道两个位置,

  1. 您指向的曲线上的一个点,
  2. 要放置文本的轴内的一个点
  3. 例如,您可以使用水平峰值点,并使用类似于图例标签的标签对其进行注释。假设文本位置具有以下x坐标

    annot_txt_pose = [2.0e-2, 2.0e-2, 1.5e-2]
    

    虽然假设y坐标与注释y坐标相同。然后在每个绘图命令之后,您可以使用以下代码来注释曲线

    label_str = "%s"%t1[s]
    # maximum x value annotation 
    annot_idx = np.argmax(KE_h)
    # annotation arrow tip position 
    arrow_tip = KE_h[annot_idx],Y4[annot_idx]
    # annotation text position 
    text_pos = annot_txt_pose[s],Y4[annot_idx]
    plt.plot(arrow_tip[0], arrow_tip[1], 'o')
    ax.annotate(label_str, xy=arrow_tip, xytext=text_pos, arrowprops=dict(facecolor='black', shrink=0.05))
    

    需要展开图形窗口以清楚地看到注释。示例文件的结果如下所示 enter image description here