I am new to python! I am trying to write a program that reads multiple csv files, gets the data columns and plots them on a scatter plot. Then the user will interact with each plot and select a point. This data point will change colour and a message will be prompted to ask the user whether they are happy with this selection. If the user selects yes, the index of this point will be returned and used for analysis and the next data set will be plotted and the cycle restarts. If ths user selects no, then the data point is changed to the original colour, the index is not returned and the user is prompted to select another point.
This is what I have tried.
However a few things arent working
- The colour doesnt change to red when the data point is selected
- the index is not returned correctly. For example: It prints out that the 'returned' 'selected_index' is 14 when it shouldve been 1223 or 1273 etc.
import os
import tkinter as tk
from tkinter import filedialog, messagebox
import pandas as pd
from openpyxl import Workbook
import numpy as np
from statistics import mean
import math as M
from scipy import stats
import matplotlib.pyplot as plt
import mplcursors
def on_pick(event,disp_list,load_list,F_vs_D_plot):
ind = event.ind[0]
print(ind)
F_vs_D_plot.set_facecolors(['red' if i == ind else 'blue' for i in range(len(disp_list))])
# F_vs_D_plot.set_color(ind,'red')
# plt.scatter(disp_list[ind],load_list[ind],color = 'red')
plt.draw()
confirmation = messagebox.askyesno("Confirmation", "Are you sure you want to select this point?")
if confirmation:
selected_index = ind
# print(f"Selected point index: {selected_index}")
#ask if user wants to close plot and move onto next file
# if yes, close plot
# if no, select again and overwrite previous selection for that file
plt.close()
return selected_index
def graph_method(disp_list, load_list):
selectedPoint = None
fig, ax = plt.subplots()
mplcursors.cursor(hover=True)
F_vs_D_plot = ax.scatter(disp_list, load_list, picker=True, color = 'blue')
selected_index = fig.canvas.mpl_connect('pick_event',lambda event: on_pick(event,disp_list,load_list,F_vs_D_plot))
print('This is the selected index',selected_index)
ax.set_xlabel('Displacement (mm)')
ax.set_ylabel('Load (g)')
ax.set_title(file_name)
plt.show()
def main()
disp_list = random.randint(100, size=(1000))
load_list = random.randint(100, size=(1000))
graph_method(disp_list, load_list)
OK, your code still not clear to me, kind of not exacty an MRE as per SO guidelines ( How to create a Minimal, Reproducible Example ) ,
ended up with :
Running the code I get this plot :
Selecting, clicking on it , one of the dot/points it gets red (see arrowhead) :
And clicking yes in
messagebox.askyesnomessagebox I get followingoutput :
I guess you need to embed yur plot in Tkinter to get the messagebox working properly, see Matplotlib Event Handlers not being Called when Embedded in Tkinter for more about it.
Other interesting link are :
Picking on a scatter plot matplotlib example, showing the use of
event.indfor picking on scatter plot (a scatter plot is backed by aPathCollection) , wasnt able to find any reference about event.ind id matplotlib documentation though :and Event handling and picking in Matplotlib to learn more about it, in brief :
Sorry about not being able to explain anything in more detail/clarity , just got your question in REVIEW QUEUES , not an expert of matplotlib/tkinter.
Just want to point out that problably PyQt5 is nowadays more fashionable and efficient than Tkinter even if Tkinter is the Python interface to the Tk GUI toolkit shipped with Python