python - 用循环中计算的值注释每条曲线

标签 python numpy matplotlib

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

我还想自动更新图表中的图例,即。图中的每条曲线应对应于 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. 您所指向的曲线上的一个点,以及
  2. 轴内要放置文本的点

例如,您可以使用水平峰值点,并使用类似于图例标签的标签对其进行注释。假设文本位置具有以下 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))

需要扩大图形窗 Eloquent 能清楚地看到注释。示例文件的结果如下所示 enter image description here

关于python - 用循环中计算的值注释每条曲线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35954065/

相关文章:

python - 诊断和提高计算速度

python - 将 matplotlib 绘图轴设置为数据框列名称

python-2.7 - matplotlib:从图中删除补丁

python - 警告 :tensorflow:create_partitioned_variables is deprecated

python - 如何使用groupby - pandas按时间频率进行计数

python - 两个 numpy 数组的逐元素减法

python - 不均匀形状阵列的哈达玛积

matplotlib - 如何在 stackplot 中使用 Matplotlib 代理艺术家?

python - 如何使用 OpenCV 获取视频的时长

python - 旋转并重命名 Pandas 数据框