我正在繪制來自多個來源的資料并使用 SpanSelector 在特定事件期間分析資料。我可以從每個子圖中選擇資料并提取資料。但是,當我在新的子圖中進行新選擇時,我希望前一個子圖中的選擇消失。
有span.set_visible(True/False)。但要使它起作用,我需要知道選擇了哪個子圖。我試圖找到使用 lambda 函式,但它目前無法正常作業。
我先試過:
for signal in self.signals:
self.span[k] = SpanSelector(
self.ax[k],
onselect = lambda min, max : self.onselect_function(min, max, k),
# onselect = self.onselect_function,
direction = 'horizontal',
minspan = 1,
useblit = True,
interactive = True,
button = 1,
props = {'facecolor': 'red', 'alpha':0.5},
drag_from_anywhere = True
)
k = 1
def onselect_function(self, min_value, max_value, selected_graph)
...
selected_graph = 3但無論我選擇哪個子圖,它都會繼續發送 selected_graph 的值。有 3 個子圖 (k = 0 - 2)。
我認為這是因為 k 不在名稱空間中,我嘗試了:
onselect = lambda min, max, k : self.onselect_function(min, max, k)
但是現在,我收到以下錯誤:
File "C:\Users\Ashu\miniconda3\envs\my_env\lib\site-packages\matplotlib\cbook\__init__.py", line 287, in process
func(*args, **kwargs)
File "C:\Users\Ashu\miniconda3\envs\my_env\lib\site-packages\matplotlib\widgets.py", line 1958, in release
self._release(event) File "C:\Users\Ashu\miniconda3\envs\my_env\lib\site-packages\matplotlib\widgets.py", line 2359, in _release
self.onselect(vmin, vmax)
TypeError: <lambda>() missing 1 required positional argument: 'k'
Ideally, I would want the selection to highlight the x-axis range in all subplots (I can still do that manually as I have info on what range is being selected, as shown in the figure with dashed lines). But I need the previous selection to disappear when the new selection begins.
Example of how it currently displays. The last selection was made in the top graph, so each graph shows the textual information for that selection (51-53), but the highlights in the bottom two graphs are in the wrong parts. I tried clearing axes as well but that also doesn't work.

Edit: Adding minimal reproducible example
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
from random import randrange
import math
plt.style.use('seaborn')
noOfDataToShow = 10
noOfSignals = 3
fig, ax = plt.subplots(nrows = noOfSignals, ncols = 1)
x_pos = []
signal_data_holder = []
for i in range(noOfDataToShow):
x_pos.append(i)
for i in range(noOfSignals):
temp = []
for j in range (noOfDataToShow):
temp.append(randrange(0,10))
signal_data_holder.append(temp)
def onselect_function(min_value, max_value, selected_graph = 0):
k = 0
for param in signal_data_holder:
ax[k].cla()
ax[k].set_ylim([0,10])
ax[k].plot(x_pos, param, label = str (math.trunc(param[noOfDataToShow - 1])))
ax[k].legend(loc = "upper left")
k = 1
#******Calculating Min_Max (Can be ignored) ******#
min_value = math.floor(min_value)
max_value = math.ceil(max_value)
min_value_data = [None] * noOfSignals
max_value_data = [None] * noOfSignals
if (min_value < 0):
min_value = 0
if (max_value >= noOfDataToShow):
max_value = noOfDataToShow
for k in range(noOfSignals):
min_value_data = signal_data_holder[k][min_value]
max_value_data = signal_data_holder[k][min_value]
for i in range(min_value, max_value):
if (signal_data_holder[k][i] < min_value_data):
min_value_data = signal_data_holder[k][i]
elif (signal_data_holder[k][i] > max_value_data):
max_value_data = signal_data_holder[k][i]
labelText = "Min_Value: " str (min_value_data) "\n"
labelText = "Max_Value: " str (max_value_data) "\n"
labelText = "Range: " str (min_value) "-" str (max_value) "\n"
ax[k].legend(labels = [labelText], loc = "upper left")
print(min_value_data, max_value_data)
ax[k].axvline(min_value, color = 'red', linestyle = 'dashed')
ax[k].axvline(max_value, color = 'red', linestyle = 'dashed')
fig.canvas.draw()
#******Calculating Min_Max (Can be ignored) ******#
return min_value, max_value
span = [None] * noOfSignals
for k in range(noOfSignals):
span[k] = SpanSelector(
ax[k],
# onselect = lambda min, max, k : onselect_function(min, max, k),
# onselect = lambda min, max : onselect_function(min, max, k),
onselect = onselect_function,
direction = 'horizontal',
minspan = 1,
useblit = True,
interactive = True,
button = 1,
props = {'facecolor': 'red', 'alpha':0.5},
drag_from_anywhere = True
)
k = 0
for param in signal_data_holder:
ax[k].cla()
ax[k].set_ylim([0,10])
ax[k].plot(x_pos, param, label = str (math.trunc(param[noOfDataToShow - 1])))
ax[k].legend(loc = "upper left")
k = 1
plt.show()
uj5u.com熱心網友回復:
我不認為您可以直接檢索鏈接到跨度選擇器的軸物件(或者至少,我不知道如何)。但是,我們也可以收集最后一次滑鼠點擊的軸物件:
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
import numpy as np
#sample data
fig, axis = plt.subplots(3)
for i, ax in enumerate(axis):
t=np.linspace(-i, i 1 , 100)
ax.plot(t, np.sin(2 * np.pi * t))
#list to store the axis last used with a mouseclick
curr_ax = []
#detect the currently modified axis
def on_click(event):
if event.inaxes:
curr_ax[:] = [event.inaxes]
#modify the current axis objects
def onselect(xmin, xmax):
#ignore if accidentally clicked into an axis object
if xmin==xmax:
return
#set all span selectors invisible accept the current
for ax, span in zip(axis, list_of_spans):
if ax != curr_ax[0]:
span.set_visible(False)
#do something with xmin, xmax
print(xmin, xmax)
fig.canvas.draw_idle()
#collect span selectors in a list in the same order as their axes objects
list_of_spans = [SpanSelector(
ax,
onselect,
"horizontal",
useblit=True,
props=dict(alpha=0.5, facecolor="tab:blue"),
interactive=True,
drag_from_anywhere=True
)
for ax in axis]
plt.connect('button_press_event', on_click)
plt.show()
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/440768.html
