Hi,
Forgive my little knowledge of tkinter, but I am trying to integrate the below code, which works well in Jupyter Lab into a tkinter GUI. For context, this is a scatter plot that on selecting any of the options changes the color of the points.
Here is some example code that works in Jupyter Lab:
%matplotlib ipympl
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import mpl_interactions.ipyplot as iplt
def cluster_colouring(x, y, n_clusters, hashtags):
if hashtags == '2 Agree':
colour_list = agree
else:
colour_list = agree3
if n_clusters == 'All':
return colour_list
elif n_clusters == 'News':
color_array = np.array([list(color) for color in colour_list], dtype=np.float64)
correct = np.array([0, 0.753, 1, 1], dtype=np.float64)
idx = np.where(np.any(color_array != correct, axis=1))[0]
color_array[idx, -1] = 0.01
return color_array
elif n_clusters == 'Unclear':
color_array = np.array([list(color) for color in colour_list], dtype=np.float64)
correct = np.array([0.388, 0.388, 0.388, 1.0], dtype=np.float64)
idx = np.where(np.any(color_array != correct, axis=1))[0]
color_array[idx, -1] = 0.01
return color_array
agree3 = [(0.412, 1.0, 0.431, 1.0),
(0.388, 0.388, 0.388, 1.0),
(0.388, 0.388, 0.388, 1.0),
(0.388, 0.388, 0.388, 1.0)] # RGBA value list
agree = [ (0.388, 0.388, 0.388, 1.0),
(0.412, 1.0, 0.431, 1.0),
(1.0, 0.0, 0.0, 1.0),
(0.388, 0.388, 0.388, 1.0)]
data = np.ndarray([[ -3.7766423, -10.52704 ], [ 0.79021263, -14.534051 ], [ -4.0262637, -10.065537 ], [ -0.71750355, -11.4191885 ]]) # Numpy array with x and y values for each point.
fig, ax = plt.subplots(sharex=True, sharey=True)
controls = iplt.scatter(x=data[:, 0],
y=data[:, 1],
s=7,
linewidth=0.1,
n_clusters= {('All', 'News', 'Unclear')},
edgecolors='gray',
c=cluster_colouring,
hashtags={('2 Agree', '3 Agree')}
)
plt.axis('off')
plt.show()
Here is how I tried to integrate it into tkinter:
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import mpl_interactions.ipyplot as iplt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
matplotlib.use('TkAgg')
def cluster_colouring(x, y, n_clusters, hashtags):
if hashtags == '2 Agree':
colour_list = agree
else:
colour_list = agree3
if n_clusters == 'All':
return colour_list
elif n_clusters == 'News':
color_array = np.array([list(color) for color in colour_list], dtype=np.float64)
correct = np.array([0, 0.753, 1, 1], dtype=np.float64)
idx = np.where(np.any(color_array != correct, axis=1))[0]
color_array[idx, -1] = 0.01
return color_array
elif n_clusters == 'Unclear':
color_array = np.array([list(color) for color in colour_list], dtype=np.float64)
correct = np.array([0.388, 0.388, 0.388, 1.0], dtype=np.float64)
idx = np.where(np.any(color_array != correct, axis=1))[0]
color_array[idx, -1] = 0.01
return color_array
agree3 = [(0.412, 1.0, 0.431, 1.0),
(0.388, 0.388, 0.388, 1.0),
(0.388, 0.388, 0.388, 1.0),
(0.388, 0.388, 0.388, 1.0)] # RGBA value list
agree = [ (0.388, 0.388, 0.388, 1.0),
(0.412, 1.0, 0.431, 1.0),
(1.0, 0.0, 0.0, 1.0),
(0.388, 0.388, 0.388, 1.0)]
data = np.ndarray([[ -3.7766423, -10.52704 ], [ 0.79021263, -14.534051 ], [ -4.0262637, -10.065537 ], [ -0.71750355, -11.4191885 ]]) # Numpy array with x and y values for each point.
root = tk.Tk()
fig, ax = plt.subplots(sharex=True, sharey=True)
controls = iplt.scatter(x=data[:, 0],
y=data[:, 1],
s=7,
linewidth=0.1,
n_clusters= {('All', 'News', 'Unclear')},
edgecolors='gray',
c=cluster_colouring,
hashtags={('2 Agree', '3 Agree')}
)
plt.axis('off')
plt.show()
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.update()
button_quit = tk.Button(master=root, text="Quit", command=root.destroy)
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
tk.mainloop()
I get it to show, both the plot and the buttons. But on button press, nothing changes, and I get the following error (reappearing every time I press a button):
Traceback (most recent call last):
File "/Users/redacted/miniforge3/envs/VIZ/lib/python3.11/site-packages/matplotlib/cbook/__init__.py", line 309, in process
func(*args, **kwargs)
File "/Users/redacted/miniforge3/envs/VIZ/lib/python3.11/site-packages/mpl_interactions/helpers.py", line 344, in changeify_radio
update({"new": labels.index(val)})
TypeError: Controls.slider_updated() missing 1 required positional argument: 'values'
However, when using the below example from the docs, everything works well (sliders change the plot and no errors come up):
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import mpl_interactions.ipyplot as iplt
import tkinter as tk
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
matplotlib.use('TkAgg')
root = tk.Tk()
x = np.linspace(0,np.pi,100)
tau = np.linspace(1,10, 100)
beta = np.linspace(.001,1)
def f(x, tau, beta):
return np.sin(x*tau)*x**beta
fig, ax = plt.subplots()
controls = iplt.plot(x, f, tau=tau, beta=beta)
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.update()
button_quit = tk.Button(master=root, text="Quit", command=root.destroy)
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
tk.mainloop()
So any help would be appreciated! This is on Mac, M1, and using Pycharm.