I have a plot of data points with 2 GUI buttons. I want to click one button and then select points on the plot which will be stored in one array. I then want to click the other button and select additional points in the plot to store in a different array.
My initial attempt was to combine the code provide in these two links:
Select n data points from plot
https://matplotlib.org/3.1.1/gallery/widgets/buttons.html
Clicking the first button and selecting points functions as expected. However, selecting the second button and clicking addition points does not close the connection from the first button.
I've attempted to use .canvas.mpl_diconnect(cid) various ways but to no avail. I cannot seem to figure out how to initialize the cid and pass it through the class.
Below is sample output data from selection, and toy code to replicate.
SAMPLE OUTPUT FROM SELECTION:
# After clicking 'Buy' Button
# data point selections correctly stored in manual_buy array
Select Buy Points
Buy onpick point: ((736551.0, 12.12),)
Buy onpick point: ((736562.0, 12.05),)
# After clicking 'Sell' Button
# data points incorrectly being stored in manual_buy array and manual_sell array
Select Sell Points
Buy onpick point: ((736556.0, 13.02),)
Sell onpick point: ((736556.0, 13.02),)
Buy onpick point: ((736573.0, 13.19),)
Sell onpick point: ((736573.0, 13.19),)
Toy Code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
from datetime import datetime
x = np.arange(0, 10, 1)
y = np.sin(x)
fig_3 = plt.figure()
ax1 = fig_3.add_subplot(111)
plt.subplots_adjust(bottom=0.2)
# Candlestick
ax1.plot(x, y, '-o', picker=1) # 5 points tolerance
ax1.grid(True)
ax1.set_axisbelow(True)
ax1.set_title('Manual Buy / Sell Selection: ', color='white')
ax1.set_facecolor('black')
ax1.figure.set_facecolor('#121212')
ax1.tick_params(axis='x', colors='white')
ax1.tick_params(axis='y', colors='white')
manual_buy = []
manual_sell = []
#https://matplotlib.org/3.1.3/users/event_handling.html
def buy_onpick(event):
thisline = event.artist
xdata = thisline.get_xdata()
ydata = thisline.get_ydata()
ind = event.ind
point = tuple(zip(xdata[ind], ydata[ind]))
dt = datetime.fromordinal(xdata[ind])
buy_str = "BUY"
buy_num = 1
point_data = np.array([[dt, buy_str, buy_num]])
manual_buy.append(point_data)
print('Buy onpick point:', point)
def sell_onpick(event):
thisline = event.artist
xdata = thisline.get_xdata()
ydata = thisline.get_ydata()
ind = event.ind
point = tuple(zip(xdata[ind], ydata[ind]))
dt = datetime.fromordinal(xdata[ind])
sell_str = "SELL"
sell_num = 0.5
point_data = np.array([[dt, sell_str, sell_num]])
manual_buy.append(point_data)
print('Sell onpick point:', point)
class Buy_Sell:
def Buy(self, event):
print('\nSelect Buy Points')
fig_3.canvas.mpl_connect('pick_event', buy_onpick)
def Sell(self, event):
print('\nSelect Sell Points')
fig_3.canvas.mpl_connect('pick_event', sell_onpick)
def Save(self, event):
print('Would have saved data')
#Add functionality to save data
print('Saved')
callback = Buy_Sell()
axbuy = plt.axes([0.59, 0.05, 0.1, 0.075])
axsell = plt.axes([0.7, 0.05, 0.1, 0.075])
axsave = plt.axes([0.81, 0.05, 0.1, 0.075])
bbuy = Button(axbuy, 'Buy')
bbuy.on_clicked(callback.Buy)
bsell = Button(axsell, 'Sell')
bsell.on_clicked(callback.Sell)
bsave = Button(axsave, 'Save')
bsave.on_clicked(callback.Save)