在 matplotlib 上用两个不同的 time/x-axis 数据绘图?
Plotting with two data different time/x-axis on matplotlib?
我的目标是生成这样的东西, but my try looks like this
问题是我使用了两个 CSV 数据,即使它们的时间范围相同,其中一个有很多时间间隔,比如 2399 左右,另一个是 73。
我正在使用 sharex="All" 命令以及我可以从互联网上找到的任何内容,但它给出运行时错误“定位器试图生成 119857 个滴答声([-113.5,...,2383.5]),超过 Locator.MAXTICKS (1000)"
我的输出生成代码如下:
fig, (ax1, ax2,ax3,ax4) = plt.subplots(4, 1,figsize=(10,7), sharex="all")
fig.subplots_adjust(bottom=0.2)
ax1.plot( df.time, df['B'], color='k')
ax1.plot( df.time, df['Bx'], color='r')
ax1.plot( df.time, df['By'], color='b')
ax1.plot( df.time, df['Bz'], color='g')
ax1.xaxis.grid(True,alpha=0.3)
ax1.set_ylabel('Bx,By,Bz,B[nT]')
ax2.plot(df1.time, df1['v_total'],color='k')
ax2.plot(df1.time, df1['Vx'],color='r')
ax2.plot(df1.time, df1['Vy'],color='b')
ax2.plot(df1.time, df1['Vz'],color='g')
ax2.xaxis.grid(True,alpha=0.3)
ax2.set_ylabel('Vx,Vy,Vz,V[km/s]')
ax3.plot(df1.time, df1['n'],color='k')
ax3.xaxis.grid(True,alpha=0.3)
ax3.set_ylabel('Np[1/cm^3]')
ax4.plot(df1.time, df1['T'],color='k')
ax4.xaxis.grid(True,alpha=0.3)
ax4.set_ylabel('T[k]')
minutes = mdates.MinuteLocator(byminute=np.arange(0,60,15),interval=2)
minutes_fmt = mdates.DateFormatter('%H:%M')
ax4.xaxis.set_major_locator(minutes)
ax4.xaxis.set_major_formatter(minutes_fmt)
ax4.tick_params(axis='x', labelrotation=45)
fig.suptitle('FF shock May 07 2007')
plt.savefig('WindIP.png')
plt.savefig('WindIP.pdf')
plt.show()
我的两个数据是:
https://drive.google.com/file/d/1uqmynE78dMM_23ITVBsdu7-5tPbnQ9gC/view?usp=sharing
https://drive.google.com/file/d/17kj8MM-agNkS22J5sRGGicdQHCK5EGYL/view?usp=sharing
我使用以下命令从纪元更改为时间
df['epoch'] = pd.to_datetime(df.epoch, format='%Y-%m-%dT%H:%M:%S.%f')
df['time'] = df['epoch'].dt.strftime('%H:%M:%S')
df1['epoch'] = pd.to_datetime(df1.epoch, format='%Y-%m-%dT%H:%M:%S.%f')
df1['time'] = df1['epoch'].dt.strftime('%H:%M:%S')
而对于T值
m_p=1.6726219*10** -27
K_b=1.38064852*10** -23
df1['nVth']=1000*df1['V_th']
df1['T']=(df1['nVth']**2*m_p)/(2*K_b)
那么,如何减少刻度以及对齐两个时间间隔并将一个时间间隔显示为x轴?
另一个小问题是如何在我的目标图中放置红色垂直线?我试过 axvline,但没有成功。感谢您的关心和帮助。
转向一个答案,这样我可以写得更清楚,你可以像这样合并数据框(从你的问题中可以看出 epoch
在两者中是相同的并且 pd.to_datetime()
已经被应用) :
df_merged = df.set_index("epoch").merge(df1.set_index("epoch"),
left_index=True, right_index=True,
how="outer")
然后使用 df_merged.index
作为 x-axis,并使用 df_merged["B"]
等作为列,所有内容都应该对齐。 (编辑:考虑到这一点,在 time
列上合并可能更容易,因为这不会那么具体,因此不会为同一天的两个数据框创建重复的行。 )
然后再次针对所有图表中的线,@bb1 here 的答案给出了答案,使用:
gs = fig.add_gridspec(3, 2)
# ...
# background axes object for plotting the vertical line
ax = fig.add_subplot(gs[:, :], sharex = ax1)
# set background color to transparent and turn off the frame
ax.patch.set_alpha(0)
ax.axis("off")
# plot the vertical line
ax.axvline(20, c='r')
您可以尝试使用它来满足您的特定要求。您可以轻松复制最后一行并使用 ls="--"
绘制虚线!
我的目标是生成这样的东西
问题是我使用了两个 CSV 数据,即使它们的时间范围相同,其中一个有很多时间间隔,比如 2399 左右,另一个是 73。 我正在使用 sharex="All" 命令以及我可以从互联网上找到的任何内容,但它给出运行时错误“定位器试图生成 119857 个滴答声([-113.5,...,2383.5]),超过 Locator.MAXTICKS (1000)"
我的输出生成代码如下:
fig, (ax1, ax2,ax3,ax4) = plt.subplots(4, 1,figsize=(10,7), sharex="all")
fig.subplots_adjust(bottom=0.2)
ax1.plot( df.time, df['B'], color='k')
ax1.plot( df.time, df['Bx'], color='r')
ax1.plot( df.time, df['By'], color='b')
ax1.plot( df.time, df['Bz'], color='g')
ax1.xaxis.grid(True,alpha=0.3)
ax1.set_ylabel('Bx,By,Bz,B[nT]')
ax2.plot(df1.time, df1['v_total'],color='k')
ax2.plot(df1.time, df1['Vx'],color='r')
ax2.plot(df1.time, df1['Vy'],color='b')
ax2.plot(df1.time, df1['Vz'],color='g')
ax2.xaxis.grid(True,alpha=0.3)
ax2.set_ylabel('Vx,Vy,Vz,V[km/s]')
ax3.plot(df1.time, df1['n'],color='k')
ax3.xaxis.grid(True,alpha=0.3)
ax3.set_ylabel('Np[1/cm^3]')
ax4.plot(df1.time, df1['T'],color='k')
ax4.xaxis.grid(True,alpha=0.3)
ax4.set_ylabel('T[k]')
minutes = mdates.MinuteLocator(byminute=np.arange(0,60,15),interval=2)
minutes_fmt = mdates.DateFormatter('%H:%M')
ax4.xaxis.set_major_locator(minutes)
ax4.xaxis.set_major_formatter(minutes_fmt)
ax4.tick_params(axis='x', labelrotation=45)
fig.suptitle('FF shock May 07 2007')
plt.savefig('WindIP.png')
plt.savefig('WindIP.pdf')
plt.show()
我的两个数据是: https://drive.google.com/file/d/1uqmynE78dMM_23ITVBsdu7-5tPbnQ9gC/view?usp=sharing https://drive.google.com/file/d/17kj8MM-agNkS22J5sRGGicdQHCK5EGYL/view?usp=sharing
我使用以下命令从纪元更改为时间
df['epoch'] = pd.to_datetime(df.epoch, format='%Y-%m-%dT%H:%M:%S.%f')
df['time'] = df['epoch'].dt.strftime('%H:%M:%S')
df1['epoch'] = pd.to_datetime(df1.epoch, format='%Y-%m-%dT%H:%M:%S.%f')
df1['time'] = df1['epoch'].dt.strftime('%H:%M:%S')
而对于T值
m_p=1.6726219*10** -27
K_b=1.38064852*10** -23
df1['nVth']=1000*df1['V_th']
df1['T']=(df1['nVth']**2*m_p)/(2*K_b)
那么,如何减少刻度以及对齐两个时间间隔并将一个时间间隔显示为x轴? 另一个小问题是如何在我的目标图中放置红色垂直线?我试过 axvline,但没有成功。感谢您的关心和帮助。
转向一个答案,这样我可以写得更清楚,你可以像这样合并数据框(从你的问题中可以看出 epoch
在两者中是相同的并且 pd.to_datetime()
已经被应用) :
df_merged = df.set_index("epoch").merge(df1.set_index("epoch"),
left_index=True, right_index=True,
how="outer")
然后使用 df_merged.index
作为 x-axis,并使用 df_merged["B"]
等作为列,所有内容都应该对齐。 (编辑:考虑到这一点,在 time
列上合并可能更容易,因为这不会那么具体,因此不会为同一天的两个数据框创建重复的行。 )
然后再次针对所有图表中的线,@bb1 here 的答案给出了答案,使用:
gs = fig.add_gridspec(3, 2)
# ...
# background axes object for plotting the vertical line
ax = fig.add_subplot(gs[:, :], sharex = ax1)
# set background color to transparent and turn off the frame
ax.patch.set_alpha(0)
ax.axis("off")
# plot the vertical line
ax.axvline(20, c='r')
您可以尝试使用它来满足您的特定要求。您可以轻松复制最后一行并使用 ls="--"
绘制虚线!