I have 3 plots like this in a Tkinter window
Is it possible to orient the NavigationToolbar2Tk vertically so I can place it on the left of the plot ?
I didn't find any documentation or thread about something similar.
Thanks
You need to create a derived class from NavigationToolbar2Tk to override the default horizontal orientation.
Below is an example (based on the "Embedding in Tk" example):
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import numpy as np
class VerticalNavigationToolbar2Tk(NavigationToolbar2Tk):
def __init__(self, canvas, window):
super().__init__(canvas, window, pack_toolbar=False)
# override _Button() to re-pack the toolbar button in vertical direction
def _Button(self, text, image_file, toggle, command):
b = super()._Button(text, image_file, toggle, command)
b.pack(side=tk.TOP) # re-pack button in vertical direction
return b
# override _Spacer() to create vertical separator
def _Spacer(self):
s = tk.Frame(self, width=26, relief=tk.RIDGE, bg="DarkGray", padx=2)
s.pack(side=tk.TOP, pady=5) # pack in vertical direction
return s
# disable showing mouse position in toolbar
def set_message(self, s):
pass
root = tk.Tk()
root.wm_title("Embedding in Tk")
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot().plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
toolbar = VerticalNavigationToolbar2Tk(canvas, root)
toolbar.update()
toolbar.pack(side=tk.LEFT, fill=tk.Y)
root.mainloop()
And the output:
Related
I would like to change the color of the toolbar when making a matplotlib figure in tkinter. I have managed to find and change the color of two parts. There is one remaining.
My code comes directly from https://matplotlib.org/stable/gallery/user_interfaces/embedding_in_tk_sgskip.html?highlight=embedding%20tk with three additional lines to change colors.
import tkinter
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import numpy as np
root = tkinter.Tk()
root.wm_title("Embedding in Tk")
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot().plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
color = "#d469a3"
toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.config(background=color)
toolbar._message_label.config(background=color)
toolbar.update()
button = tkinter.Button(master=root, text="Quit", command=root.quit)
button.pack(side=tkinter.BOTTOM)
toolbar.pack(side=tkinter.BOTTOM)
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
tkinter.mainloop()
This gives me the window:
What is the small, grey rectangle I have pointed out? How do I change its color?
It is an empty label. You can get a reference to it via winfo_children:
print (toolbar.winfo_children()[-2])
# .!navigationtoolbar2tk.!label
And to change its color:
toolbar.winfo_children()[-2].config(background=color)
I do not understand how correctly add matplotlib into panedwindow of tkinter.
I want to have on one side list box and matplotlib interactive plot, on the other side
I need to resize listbox and plot by dragging boundary between them
this is what is desirable
I tried this but I cannot add correctly matplot lib to paned window
from tkinter import *
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import numpy as np
root = Tk()
m = PanedWindow(root)
m.pack(fill=BOTH, expand=1)
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, master = root) # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=RIGHT, fill=BOTH, expand=1)
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=RIGHT, fill=BOTH, expand=1)
m.add(toolbar)
m.add(canvas)
lstbox2 = Listbox(selectmode=MULTIPLE, width=20, height=10)
m.add(lstbox2)
root.mainloop()
Put your canvas and toolbar in a Frame instead, and add that Frame to your paned window:
root = Tk()
...
canvas_frame = Frame(root)
canvas = FigureCanvasTkAgg(fig, master = canvas_frame)
canvas.draw()
canvas.get_tk_widget().pack()
toolbar = NavigationToolbar2Tk(canvas, canvas_frame)
toolbar.update()
toolbar.pack_configure(expand=True)
m.add(canvas_frame)
lstbox2 = Listbox(selectmode=MULTIPLE, width=20, height=10)
m.add(lstbox2)
root.mainloop()
I have a plot in a tkinter application and I am trying to change the background color of the plot using tkinter colors. I have found How to change plot background color? however, I got this error:
ValueError: Invalid RGBA argument: 'AntiqueWhite2'
...indicating I may only be able to use their subset of colors? Does anyone know how to use the tkinter colors here?
Here is what I am currently using (without color change):
self.fig = Figure(figsize=(5, 4), dpi=100)
self.canvas = FigureCanvasTkAgg(self.fig, master=self.master) # A tk.DrawingArea
self.canvas.draw()
self.ax = self.fig.add_subplot(111)
import tkinter
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import numpy as np
root = tkinter.Tk()
root.geometry("770x633+745+171")
Frame1 = tkinter.Frame(root)
Frame1.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.5)
root.wm_title("Embedding in Tk")
t = np.arange(0, 3, .01)
fig = Figure(figsize=(5, 3), dpi=80,facecolor = 'k')
axes1 =fig.add_subplot(111)
# axes1.axis('tight')
axes1.autoscale(enable=True, axis='y', tight=True)
axes1.plot(t, 2 * np.sin(2 * np.pi * t))
# axes1.set_axis_bgcolor('k')
axes1.set_facecolor('k')
axes1.grid(color = 'w')
for label in axes1.xaxis.get_ticklabels():
# label is a Text instance
label.set_color('w')
for label in axes1.yaxis.get_ticklabels():
# label is a Text instance
label.set_color('w')
# label.set_rotation(45)
# label.set_fontsize(1)
for line in axes1.yaxis.get_ticklines():
# line is a Line2D instance
line.set_color('w')
for line in axes1.xaxis.get_ticklines():
# line is a Line2D instance
line.set_color('w')
# line.set_markersize(25)
# line.set_markeredgewidth(3)
for line in axes1.xaxis.get_gridlines():
line.set_color('w')
for line in axes1.yaxis.get_gridlines():
line.set_color('w')
line.set_markeredgewidth(8)
axes1.yaxis.grid(color='w',linewidth=1)
# axes1.set_xmargin(0.9)
axes1.set_xlabel("Time(ns)")
axes1.xaxis.label.set_color('w')
axes1.set_ylabel("Amplitude(mV)")
axes1.yaxis.label.set_color('w')
axes1.xaxis.grid(color='w',linewidth=1)
axes1.spines['bottom'].set_color('white')
axes1.spines['top'].set_color('white')
axes1.spines['left'].set_color('white')
axes1.spines['right'].set_color('white')
canvas = FigureCanvasTkAgg(fig, master=Frame1) # A tk.DrawingArea.
canvas.get_tk_widget().configure(bg='black')
canvas.get_tk_widget().grid(row=1,column=0)
canvas.get_tk_widget().grid(row=1,column=0)
# canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
canvas.draw()
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, canvas, toolbar)
canvas.mpl_connect("key_press_event", on_key_press)
fig.tight_layout()
def _quit():
root.quit() # stops mainloop
root.destroy() # this is necessary on Windows to prevent
# Fatal Python Error: PyEval_RestoreThread: NULL tstate
button = tkinter.Button(master=root, text="Quit", command=_quit)
button.pack(side=tkinter.BOTTOM)
tkinter.mainloop()
# plt.tight_layout()
This is an example for change the background as black and change the label, grid, tick labels, ... color.
I'm trying to set up some program that includes a matplotlib graph and tkinter buttons and whatnot below it. However, the matplotlib graph occupies the entire window overlaying the tkinter buttons and stuff.
I'd tried using pack, but it doesn't let me put stuff side by side, so I'd like the tkinter widgets to be arranged with .grid or coordinates.
from tkinter import *
from tkinter import StringVar
import tkinter
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
def eggs():
print("eggs")
root = Tk()
root.geometry("600x600")
root.title("eggs")
fig = Figure(figsize=(10, 6), dpi=100)
x = [1,2,3,4]
y = [1,2,3,4]
AS = [10/2**0]
fig.add_subplot(111).plot(x,y)
#fig.add_subplot(111).plot(AS)
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
testbutton = Button(root, text = "test button", command = eggs)
testbutton.place(x=100, y=550)
root.mainloop()
Wanting the top part of the window to be occupied by the graph and the buttons and other additional stuff below it.
You can use one Frame to keep graph and its toolbar vertically, and another Frame to keep buttons horizontally. And then you can use pack() to put one Frame at top top and other at the bottom.
The only problem makes figsize=(10, 6) which needs more space than "600x600"
BTW: you can use Button(toolbar, ...) to add button to NavigationToolbar2Tk - see "my tool".
]1
import tkinter as tk
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
# --- functions ---
def eggs():
print("eggs")
# --- main ---
x = [1, 2, 3, 4]
y = [1, 2, 3, 4]
AS = [10/2**0]
# ---
root = tk.Tk()
root.geometry("600x600")
root.title("eggs")
# ---
frame_top = tk.Frame(root)
frame_top.pack(fill='both', expand=True)
fig = Figure(dpi=100) # figsize=(10, 6),
fig.add_subplot(111).plot(x,y)
#fig.add_subplot(111).plot(AS)
canvas = FigureCanvasTkAgg(fig, master=frame_top) # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(fill='both', expand=True)
toolbar = NavigationToolbar2Tk(canvas, frame_top)
toolbar.update()
tool = tk.Button(toolbar, text="my tool")
tool.pack(side='left')#, fill='x', expand=True)
# ---
frame_bottom = tk.Frame(root)
frame_bottom.pack(fill='x')
button1 = tk.Button(frame_bottom, text="button1")
button1.pack(side='left', fill='x', expand=True)
button2 = tk.Button(frame_bottom, text="button2")
button2.pack(side='left', fill='x', expand=True)
button3 = tk.Button(frame_bottom, text="button3")
button3.pack(side='left', fill='x', expand=True)
# ---
root.mainloop()
I am making an embeded matplotlib graph GUI program.
I want to make overlaid graphs in upper graph window when users click the "Update" button.
But, There is no response when I click "Update" button.
I am using Spyder Python 3.6 Version.
Below is what I wrote.
import matplotlib.pyplot as plt
import csv
import numpy as np
import tkinter as tk
from tkinter import ttk
import matplotlib as plt
plt.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from matplotlib import style
class Analysis_app(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
tk.Tk.wm_title(self, "SIM Analyser")
right_f = tk.Frame(self)
right_f.pack(side=tk.RIGHT)
self.entry1 = ttk.Entry(right_f).pack()
self.entry2 = ttk.Entry(right_f).pack()
self.entry3 = ttk.Entry(right_f).pack()
self.entry4 = ttk.Entry(right_f).pack()
self.entry5 = ttk.Entry(right_f).pack()
Button1 = ttk.Button(right_f, text='Update', command=self.plot).pack(side=tk.BOTTOM)
self.left_f = tk.Frame(self)
self.left_f.pack(side=tk.LEFT)
f = Figure(figsize=(10,6), dpi=100)
self.upplot = f.add_subplot(211)
self.botplot = f.add_subplot(212)
a =self.upplot
a.clear()
a.plot([1,2,3],[1,2,3])
canvas = FigureCanvasTkAgg(f, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
toolbar = NavigationToolbar2TkAgg(canvas, self)
toolbar.update()
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.mainloop()
def plot(self):
a =self.upplot
a.clear()
a.plot([1,2,3],[5,2,5])
You get no response because the canvas is not redrawn after changing the content of the plot.
The solution is to replace canvas = FigureCanvasTkAgg(f, self) by self.canvas = FigureCanvasTkAgg(f, self) so that you can redraw the canvas in self.plot:
def plot(self):
a = self.upplot
a.clear()
a.plot([1,2,3],[5,2,5])
self.canvas.draw_idle()
And then you should see the change after clicking on the update button.