问题描述
在 backtrader
的 matplotlib
实现视频中
这是将数据存储在全局变量中并移动行(而不是删除和重新创建它们)的替代实现:
将numpy导入为np导入matplotlib.pyplot作为plt导入放大器def crosshair(sel):x = sel.target [0]y1 = np.interp(x,plot1x,plot1y)y2 = np.interp(x,plot2x,plot2y)sel.annotation.set_visible(False)hline1.set_ydata([y1])vline1.set_xdata([x])hline2.set_ydata([y2])vline2.set_xdata([x])hline1.set_visible(真)vline1.set_visible(真)hline2.set_visible(真)vline2.set_visible(真)无花果= plt.figure(figsize =(15,10))ax1 = plt.subplot(2, 1, 1)ax2 = plt.subplot(2,1,2,sharex = ax1)plot1, = ax1.plot(np.array(np.random.uniform(-1, 1, 100).cumsum()))plot2, = ax2.plot(np.array(np.random.uniform(-1, 1, 100).cumsum()))plot1x = plot1.get_xdata()plot1y = plot1.get_ydata()plot2x = plot2.get_xdata()plot2y = plot2.get_ydata()hline1 = ax1.axhline(plot1y [0],color ='k',ls =':',visible = False)vline1 = ax1.axvline(plot1x [0],color ='k',ls =':',visible = False)hline2 = ax2.axhline(plot2y [0],color ='k',ls =':',visible = False)vline2 = ax2.axvline(plot2x[0], color='k', ls=':',visible=False)cursor = mplcursors.cursor([plot1,plot2],hover = True)cursor.connect('添加', 十字准线)plt.show()
In this video of backtrader
's matplotlib
implementation https://youtu.be/m6b4Ti4P2HA?t=2008 I can see that a default and very fast and CPU saving crosshair mouse cursor seems to exist in matplotlib
.
I would like to have the same kind of mouse cursor for a simple multi subplot plot in matplotlib
like this:
import numpy as np
import matplotlib
matplotlib.use('QT5Agg')
matplotlib.rcParams['figure.figsize'] = (20.0, 22.0)
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = plt.subplot(2, 1, 1)
ax2 = plt.subplot(2, 1, 2, sharex=ax1)
ax1.plot(np.array(np.random.rand(100)))
ax2.plot(np.array(np.random.rand(100)))
plt.show()
So, if I am with my mouse in the lower subplot, I want to see directly and very precisely, which value of x/y in the lower plot corresponds to which value pair in the upper plot.
I have found other solutions to do this but they seem to be very slow compared to the implementation in the video.
You can create a crosshair cursor via mplcursors. sel.extras.append()
takes care that the old cursor is removed when a new is drawn. With sel.annotation.set_text
you can adapt the popup annotation shown. To leave out the annotation, use sel.annotation.set_visible(False)
. To find the corresponding y-value in the other subplot, np.interp
with the data extracted from the curve can be used.
import numpy as np
import matplotlib.pyplot as plt
import mplcursors
def crosshair(sel):
x, y2 = sel.target
y1 = np.interp( sel.target[0], plot1.get_xdata(), plot1.get_ydata() )
sel.annotation.set_text(f'x: {x:.2f}\ny1: {y1:.2f}\ny2: {y2:.2f}')
# sel.annotation.set_visible(False)
hline1 = ax1.axhline(y1, color='k', ls=':')
vline1 = ax1.axvline(x, color='k', ls=':')
vline2 = ax2.axvline(x, color='k', ls=':')
hline2 = ax2.axhline(y2, color='k', ls=':')
sel.extras.append(hline1)
sel.extras.append(vline1)
sel.extras.append(hline2)
sel.extras.append(vline2)
fig = plt.figure(figsize=(15, 10))
ax1 = plt.subplot(2, 1, 1)
ax2 = plt.subplot(2, 1, 2, sharex=ax1)
plot1, = ax1.plot(np.array(np.random.uniform(-1, 1, 100).cumsum()))
plot2, = ax2.plot(np.array(np.random.uniform(-1, 1, 100).cumsum()))
cursor = mplcursors.cursor(plot2, hover=True)
cursor.connect('add', crosshair)
plt.show()
Here is an alternative implementation that stores the data in global variables and moves the lines (instead of deleting and recreating them):
import numpy as np
import matplotlib.pyplot as plt
import mplcursors
def crosshair(sel):
x = sel.target[0]
y1 = np.interp(x, plot1x, plot1y)
y2 = np.interp(x, plot2x, plot2y)
sel.annotation.set_visible(False)
hline1.set_ydata([y1])
vline1.set_xdata([x])
hline2.set_ydata([y2])
vline2.set_xdata([x])
hline1.set_visible(True)
vline1.set_visible(True)
hline2.set_visible(True)
vline2.set_visible(True)
fig = plt.figure(figsize=(15, 10))
ax1 = plt.subplot(2, 1, 1)
ax2 = plt.subplot(2, 1, 2, sharex=ax1)
plot1, = ax1.plot(np.array(np.random.uniform(-1, 1, 100).cumsum()))
plot2, = ax2.plot(np.array(np.random.uniform(-1, 1, 100).cumsum()))
plot1x = plot1.get_xdata()
plot1y = plot1.get_ydata()
plot2x = plot2.get_xdata()
plot2y = plot2.get_ydata()
hline1 = ax1.axhline(plot1y[0], color='k', ls=':', visible=False)
vline1 = ax1.axvline(plot1x[0], color='k', ls=':', visible=False)
hline2 = ax2.axhline(plot2y[0], color='k', ls=':', visible=False)
vline2 = ax2.axvline(plot2x[0], color='k', ls=':', visible=False)
cursor = mplcursors.cursor([plot1, plot2], hover=True)
cursor.connect('add', crosshair)
plt.show()
这篇关于如何在matplotlib中使用快速十字光标定位子图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!