0

I have a Matplotlib plot with 6 adjacent, vertical plots, all with sharey=True. When I move the cursor on any one plot, I want a horizontal cursor/marker to show on the other 5. I understand MultiCursor is the best method. I have looked at this and it works correctly when I run it, all be it on horizontal plots. My code is not running in any GUI (if it makes a difference), but nor is this demo. Matplotlib gallery demo

When I try it with my plot, nothing happens. The plot code below only links two subplots rather than all 6, but it is not functioning anyway. I have imported MultiCursor in the main body of the code.

def Raw_Plot():  #Raw Data Plot

global unitW
fig, axs=plt.subplots(1,6,constrained_layout=True, sharey=True)
fig.suptitle(tail)
axs[0].plot(df['Cone'],df['Depth'],'r-',linewidth=0.8)
axs[0].set_xlabel('$q_c$ (MPa)')
axs[0].set_ylabel('Depth (m)')
axs[0].set_title('Cone resistance',fontsize=10)
axs[0].grid()
axs[0].set_ylim(dmax,0)
axs[0].set_xlim(0,None)
axs[1].plot(df['Friction'],df['Depth'],'b-',linewidth=0.8)
axs[1].set_xlabel('$f_s$ (MPa)')
axs[1].set_title('Sleeve Friction',fontsize=10)    
axs[1].grid()
axs[1].set_xlim(0,None)
axs[1].set_ylabel('Depth (m)')
axs[2].plot(df['Pore'],df['Depth'],'g-',linewidth=0.8)
axs[2].plot(df['AmbientM'],df['Depth'],'r-',linewidth=0.8)
axs[2].plot(df['Bq'],df['Depth'],'g--',linewidth=0.8)
axs[2].set_xlabel('$U_2$, $U_0$ (MPa) & $B_q$')
axs[2].set_title('Raw, Ambient and \n Normalised Pore Pressures',fontsize=10)    
axs[2].grid()
axs[2].set_ylabel('Depth (m)')
axs[3].plot(df['Rf'],df['Depth'],'c-',linewidth=0.8,label='$R_f$')
axs[3].plot(df['Fr'],df['Depth'],'b-',linewidth=0.8, label='$F_r$')
axs[3].set_xlabel('$F_r$ & $R_f$ (%)')
axs[3].set_xlim(0,10)
axs[3].set_title('Friction Ratios',fontsize=10)
axs[3].set_ylabel('Depth (m)',fontsize=10)
axs[3].legend(loc='upper right',bbox_to_anchor=(1,1),fontsize=6.5)
axs[3].grid()
axs[4].plot(df['Qtn'],df['Depth'],'r-',linewidth=0.8)
axs[4].set_xlabel('$Q_{tn}$')
axs[4].set_ylabel('Depth (m)')
axs[4].set_title('Normalised Cone resistance',fontsize=10)
axs[4].grid()
axs[4].set_ylim(dmax,0)
axs[4].set_xlim(0,None)
axs[5].plot(df['GammaS'],df['Depth'],'c-',linewidth=0.8, label='Calculated')
axs[5].plot(df['GaDef'],df['Depth'],'b-',linewidth=1.0, label='Default '+str(unitW))
axs[5].legend(loc='upper right',bbox_to_anchor=(1,1),fontsize=6.5)
axs[5].set_xlabel('$\gamma$ $(kN/m^3)$')
axs[5].set_xlim(14,20)
axs[5].xaxis.set_major_formatter(FormatStrFormatter('%.1f'))    
axs[5].set_title('Soil Unit Weight',fontsize=10)
axs[5].set_ylabel('Depth (m)')
axs[5].grid()

fig.canvas.set_window_title(tail)
multi=MultiCursor(fig.canvas,(axs[1],axs[4]),color='r',lw=1)
plt.ion() #makes plot non-blocking - Can open multiple plots
plt.show()

3 Answers 3

0

I have solved the initial part of the problem. plt.ion() and MultiCursor seem to be mutually exclusive; if it turn off plt.ion() then MultiCursor works. The downside is that I can't have multiple Matplotlib windows open at the same time. I have opened this as a separate question here:

plt.ion() blocking MultiCursor

Sign up to request clarification or add additional context in comments.

Comments

0

At least when using Spyder as my editor, multiple plots are possible without needing plt.ion().

multi = MultiCursor(fig.... was still not being actioned ("local variable multi is assigned but never used") and there was no cursor on multiple subplots.

I have resolved this by using plt.multi = MultiCursor(fig.... This still only works on one plot at a time but at least I have the MultiCursor on which ever is the last plot to open.

Comments

0

This happens because a lot of matplotlib objects get garbage collected unless you keep references to them (the docs allude to this).

This only results in the last being saved:

for fig in figs:
    multi = MultiCursor(fig.canvas, fig.get_axes(), color='r', lw=1)

Keeping references to everything will keep the objects around:

junk = []
for fig in figs:
    multi = MultiCursor(fig.canvas, fig.get_axes(), color='r', lw=1)
    junk.append(multi)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.