Home > Mobile >  Plotting with two data different time/x-axis on matplotlib?
Plotting with two data different time/x-axis on matplotlib?

Time:06-01

My aim is to generate something like this aim, but my try looks like this my output

The problem is I am using two CSV data and even though their time range is the same, one of them has many time intervals like around 2399 and the other one is 73. I'm using sharex="All" command and whatever I can found from internet as well, but it gives runtime error "Locator attempting to generate 119857 ticks ([-113.5, ..., 2383.5]), which exceeds Locator.MAXTICKS (1000)"

My output generating code is following :

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()

My two data are: https://drive.google.com/file/d/1uqmynE78dMM_23ITVBsdu7-5tPbnQ9gC/view?usp=sharing https://drive.google.com/file/d/17kj8MM-agNkS22J5sRGGicdQHCK5EGYL/view?usp=sharing

I used following command to change from epoch to time

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')

and for T value

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)

So, how to reduce ticks as well as align two time intervals and show one time interval as x-axis? And another minor problem is how put red vertical line like in the my aim figure? I tried axvline, but no success. Thanks for your consideration and help.

CodePudding user response:

Moving to an answer so I can write more clearly, you can merge the dataframes like this (taking from your question that epoch is the same in both and pd.to_datetime() has already been applied):

df_merged = df.set_index("epoch").merge(df1.set_index("epoch"),
                                        left_index=True, right_index=True,
                                        how="outer")

Then using df_merged.index as the x-axis, and df_merged["B"] etc. as the columns, everything should align. (EDIT: thinking this through, it might be easier to merge on the time column, as this will not be so specific, so will not create duplicate rows for the two dataframes for the same day.)

Then again for the line across all charts, the answer from @bb1 here gives the answer, by using:

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')

You can play around with this to get it to suit your specific requirements. You can easily duplicate the last line and use ls="--" to plot the dashed lines too!

  • Related