Two plots, each on its own page in tkinter - python

I have two plots, which I get as a result of some calculations. I want to show each of them on a separate page. I wanted to use the answer to this question, but I don't know where to insert the code of my plots.
Below is the code for one of the graphs. For the second it is similar.
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
lf = ttk.Labelframe(root, text='Plot №1')
lf.grid(row=0, column=0, sticky='nwes', padx=3, pady=3)
fig = Figure(figsize=(10,5), dpi=100)
ax = fig.add_subplot(111)
df.plot(x='date', y=['col1', 'col2', 'col3', 'col4','col5'], ax=ax)
canvas = FigureCanvasTkAgg(fig, master=lf)
canvas.show()
canvas.get_tk_widget().grid(row=0, column=0)
root.mainloop()
And one more question, how can I show some values in each window for the corresponding plot? For example, on the page for the first plot, I need to show some three values, say
value1 = 5
value2 = 10
value3 = 15
I need to show them next to the corresponding plot.
Any advice, please?

Related

Ipywidget: How to change the widget that is displayed with click of button?

I have the code for the following 2 widgets: one widget that is a plot/slider combination (plot changes when slider is moved) and the other is a dropdown/float combination. I also have the code for two buttons: "Plot/Slider" and "Dropdown/Float".
I would like to combine all this code so that: at any time, the 2 buttons are displayed. And, depending on which button has been clicked, 1 of the 2 widgets is displayed next to the buttons (and all widgets can be interacted with).
For instance, I would like the screen to look like either of these 2 images at all times:
image1:
image 2:
Would appreciate help with figuring out how to connect/loop my current blocks of code together so that I can switch between widgets at the click of either 2 buttons. Thanks for the help.
Here is the code I currently have for each of the widgets:
BUTTONS CODE:
%matplotlib inline
from ipywidgets import *
import matplotlib.pyplot as plt
button1 = Button(description="Plot/Slider")
button2 = Button(description="Dropdown/Float")
buttons = VBox(children=[button1, button2])
all_widgets = HBox(children=[buttons])
display(all_widgets)
def change_widget(b):
print("*Button Clicked. Widget Changed*")
button1.on_click(change_widget)
button2.on_click(change_widget)
PLOT/SLIDER CODE:
%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, np.sin(x))
def update(w = 1.0):
line.set_ydata(np.sin(w * x))
fig.canvas.draw()
interact(update)
DROPDOWN/FLOAT CODE:
from ipywidgets import *
dW = Dropdown(options=['2', '1'])
rW = FloatText(200)
aW = FloatText()
def change_a(_):
aW.value = int(dW.value) * int(rW.value)
dW.observe(change_a)
rW.observe(change_a)
display(VBox(children=[dW, rW, aW]))

Creating two lines with live data using matplotlib and tkinter

I'm trying to create a graph that displays plots two lines from live data. the values that will be displayed will come from two seperate encoders but for now I'm just using randrange to get data into the program. I've found some examples using matplotlib that I've modified, but once I try to add the second value it won't work
import itertools
from tkinter import *
from tkinter import ttk
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.gridspec import GridSpec
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
x_len = 300
y_range = [0,300]
INTERVALS = 0
win = Tk()
# Set the window size
win.geometry("1024x600")
# --- Use TkAgg ---
matplotlib.use("TkAgg")
# Create a figure of specific size
figure = plt.figure(figsize=(11, 5), dpi=100)
gs = GridSpec(nrows=3, ncols=4)
#Create plot1
plot = figure.add_subplot(gs[:,0:3],)
xs = list(range(0, x_len))
ys = [0]* x_len
yc = [0]* x_len
plot.set_ylim(y_range)
line, = plot.plot(xs,ys)
def animate(i, ys,):
# get values
Pid = random.randrange(0,100)
sp = random.randrange(100,200)
# Add y to list
ys.append(Pid)
# Limit y list to set number of items
ys = ys[-x_len:]
# Update line with new Y values
line.set_ydata(ys)
return (line,)
ani = animation.FuncAnimation(figure,
animate,
fargs=(ys,),
interval=INTERVALS,
blit=True)
# Add a canvas widget to associate the figure with canvas
canvas = FigureCanvasTkAgg(figure, win)
canvas.get_tk_widget().grid(row=0, column=0)
win.mainloop()

Embedding Mapplotlib pie chart into Tkinter Gui Issue

Embedding Mapplotlib pie chart into Tkinter Gui help!
I am trying to embed a pie chart into my Tkinter window! So far I already have a frame in mind for the graph to be embedded in, frameChartsLT. This frame also already has a canvas, canvasChartsLT, placed over the entire area of the frame so I was hoping to place it on either of the of these but I keep getting the error.
AttributeError: 'tuple' object has no attribute 'set_canvas'
I checked my entire code but I can't even find anywhere where I wrote set_canvas so I am completely lost. Any help will be truly appreciated! I am also a beginner so the simpler the explanation or fix the better for me haha!
This is the portion of my code!
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# Some in-between code that sets the frame and canvas on my window
stockListExp = [ 'AMZN' , 'AAPL', 'JETS', 'CCL', 'NCLH']
stockSplitExp = [15,25,40,10,10]
plt.pie(stockSplitExp, radius=1, labels=stockListExp,autopct='%0.2f%%', shadow=True,) # 2 decimal points after plot
figChart1 = plt.pie(stockSplitExp, radius=1, labels=stockListExp,autopct='%0.2f%%', shadow=True)
plt.axis("equal")
chart1 = FigureCanvasTkAgg(figChart1,frameChartsLT)
chart1.get_tk_widget().place(x=10,y=10
You should use matplotlib.figure.Figure instead of pyplot when you combine tkinter with matplotlib. Below with modifications to your code:
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
root = tk.Tk()
frameChartsLT = tk.Frame(root)
frameChartsLT.pack()
stockListExp = ['AMZN' , 'AAPL', 'JETS', 'CCL', 'NCLH']
stockSplitExp = [15,25,40,10,10]
fig = Figure() # create a figure object
ax = fig.add_subplot(111) # add an Axes to the figure
ax.pie(stockSplitExp, radius=1, labels=stockListExp,autopct='%0.2f%%', shadow=True,)
chart1 = FigureCanvasTkAgg(fig,frameChartsLT)
chart1.get_tk_widget().pack()
root.mainloop()

TypeError: iteration over a 0-d array, using numpy and pydicom

I am trying to create a simple DICOM viewer, in which I plot the image using matplotlib and I want to show that same plot(which is a DICOM image) in tkinter, but when I run the code I get this error. please help. The error occurs when I try to plot a, but I believe it has something to do wuth the way I declared the values of x, y, and p
import pydicom
import matplotlib
matplotlib.use('TkAgg')
import numpy as np
from matplotlib.backends.backend_tkagg import
FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import *
from pydicom.data import get_testdata_files
filename = get_testdata_files('000000.dcm')
dataset = pydicom.dcmread('000000.dcm')
data = dataset.pixel_array
class mclass:
def __init__(self, window):
self.window = window
self.button=Button(window,text="check",command=self.plot)
self.button.pack()
def plot (self):
if 'PixelData' in dataset:
rows = int(dataset.Rows)
cols = int(dataset.Columns)
y=np.array(rows)
x=np.array(cols)
p=np.array(data)
fig = Figure(figsize=(6,6))
a = fig.add_subplot(111)
a.plot(p, range(2+max(y)))
canvas = FigureCanvasTkAgg(fig, master=self.window)
canvas.get_tk_widget().pack()
canvas.draw()
window = Tk()
start = mclass (window)
window.mainloop()
From the look of it your error lies here :
y=np.array(rows)
...
a.plot(p, range(2+max(y)))
You ask for the max(y), but the ds.Rows and ds.Columns you use to instantiate x and y are scalar values (and to be doubly sure you use int(ds.Rows)). This means that both x and y will be a 0-dimensional array and this would explain the thrown error, presumably on max(y). Try :
if 'PixelData' in dataset:
rows = int(dataset.Rows)
cols = int(dataset.Columns)
y=rows
x=cols
p=np.array(data)
fig = Figure(figsize=(6,6))
a = fig.add_subplot(111)
a.plot(p, range(2+y))

Matplotlib y-tick labels not showing

For some reason the y-tick and y-tick labels aren't showing up on my plot. The variable data is a pandas dataframe: rfr_scatter = pd.DataFrame({'Actual':y_test, 'Model Predicted':rfr_predictions})
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import tkinter as tk
from tkinter import *
def ScatterPlotter(notebooktab, data, test, pred):
f = Figure(figsize=(7,5), dpi=100)
ax1 = f.add_subplot(111, title="Model Performance")
for item in ([ax1.title, ax1.xaxis.label, ax1.yaxis.label] +
ax1.get_xticklabels() + ax1.get_yticklabels()):
item.set_fontsize(8)
item.set_color('black')
markersize = 0.8
alpha = 0.05
line = np.arange(min(test), min(test) + 35, 5)
data.plot.scatter(x='Actual', y='Model Predicted', ax=ax1, s=markersize, alpha=alpha)
ax1.set_xlim((min(test),max(test)))
ax1.set_ylim((pred.min(),pred.max()))
ax1.plot(line,line,clr_red,'--', label = "Perfect")
canvas = FigureCanvasTkAgg(f, notebooktab)
canvas.show()
canvas.get_tk_widget().pack()
And i get this:
I have tried setting the yticks to visible, with no luck. I'm probably missing something simple...
EDIT: removing ax1.set_ylim((pred.min(),pred.max())) gives me a couple marks on the graph, it almost looks like the label is over the text, or the text isn't finishing rendering.
Changing ax1.plot(line,line,clr_red,'--', label = "Perfect") to ax1.plot(line,line,'r--', label = "Perfect") fixed the problem

Categories