pythontkinterplotaxis

Is there a way to transform an existing X-Y plot to X-Y-Y1 plot ( to repopulate)?


I have an X-Y plot and I want to repopulate the same plot with another Y1. Basically to transform the existing X-Y plot to X-Y-Y1 plot. Because I want to automate and add multiple Ys to the same plot I thought initializing an empty int list would do the trick. The following code is my attempt:

import numpy as np
import matplotlib.pyplot as plt
from tkinter import *
from matplotlib.backends.backend_tkagg import (
     FigureCanvasTkAgg, NavigationToolbar2Tk)

class Program_Class:
    
    def __init__(self, master):

        # Main Window parameters
        Main.resizable(0,0)
        Main.geometry("900x550")
        Main.title("Main")

        # Creating a figure object with transparency
        transparent = (0, 0, 0, 0)
        plot_2D = plt.figure(figsize=(2,2), facecolor=transparent)

        # Creating axes object and attributing it the plot_2D figure
        self.axes = plot_2D.add_axes([0.1, 0.1, 0.8, 0.8])

        # Generating data which will be used for X axis
        dt = 1
        t = np.arange(0, 30, dt)
        self.x = t

        # Generating data which will be used for Y axis
        self.y = np.sin(2 * np.pi * 0.2 * t)

        # Generating data which will be used for Y1 axis
        self.y1 = np.sin(2 * np.pi * 5 * t) 

        # Creating an empty list
        self.axes_plot = [[None] for _ in range(4)]

        # Indexing the empty list with the generated data for X and Y 
        self.axes_plot[0] = self.x
        self.axes_plot[1] = self.y

        # Populatind the axes using list
        self.axes.plot(self.axes_plot, linewidth=2.0) # <----- here it give me an error
        # ValueError: Input could not be cast to an at-least-1D NumPy array

        # Drawing the object figure on top of Main Window
        color = '#%02x%02x%02x' % (196, 233, 242)
        self.Canvas_plot2D = FigureCanvasTkAgg(plot_2D, Main)
        self.Canvas_plot2D.get_tk_widget().config(bg=color, width = 400, height=300)
        self.Canvas_plot2D.get_tk_widget().place(x=300,y=71)
        self.Canvas_plot2D.draw()

        # Creating a button for adding another Y axes
        extract_2d_button=Button(Main, text="Add Y1", width=10, heigh=2, command = self.add_Y1)
        extract_2d_button.place(anchor='nw',x=10, y=460)

    # My attempt at adding another Y axis 
    def add_Y1(self):

        # Updating the list with Y1
        self.axes_plot[2] = self.x
        self.axes_plot[3] = self.y1

        # Repopulating the plot
        self.axes.plot(self.axes_plot, linewidth=2.0)
        self.Canvas_plot2D.draw()



Main = Tk()
Program_Class(Main)
Main.mainloop()

Any help would be appreciated :)

EDIT: Thank you László Hunyadi. Based on your wonderful suggestion I edited my answer.

    # Creating an empty list
    self.axes_plot = [[None] for _ in range(4)]

    # Indexing the empty list with the generated data for X and Y 
    self.axes_plot[0] = self.x
    self.axes_plot[1] = self.y

    # Populatind the axes with list inde
    self.axes.plot(self.axes_plot[0],self.axes_plot[1], linewidth=2.0) 

    # Drawing the object figure on top of Main Window
    color = '#%02x%02x%02x' % (196, 233, 242)
    self.Canvas_plot2D = FigureCanvasTkAgg(plot_2D, Main)
    self.Canvas_plot2D.get_tk_widget().config(bg=color, width = 400, height=300)
    self.Canvas_plot2D.get_tk_widget().place(x=300,y=71)
    self.Canvas_plot2D.draw()

    # Variable to be used as argument for Button command
    # In this case arg1 returns '2' and since the indexing starts from '0', arg1 can be used directly to extend the list 
    arg1 = len(self.axes_plot)

    # Creating a button for adding another Y axes
    extract_2d_button=Button(Main, text="Add Y1", width=10, heigh=2, command= lambda: self.add_Y1(arg1))
    extract_2d_button.place(anchor='nw',x=10, y=460)

# Automating adding a new Y1 to the plot by extending the list  
def add_Y1(self, a):

    # Updating the list with Y1
    self.axes_plot.append(self.y1)

    # Repopulating the plot. Axes X can be reused from self.axes_plot[0]
    self.axes.plot(self.axes_plot[0], self.axes_plot[a], linewidth=2.0)
    self.Canvas_plot2D.draw()

Solution

  • Modify the self.axes.plot calls to pass self.axes_plot[0] and self.axes_plot[1] as separate arguments, instead of passing self.axes_plot as a asingle argument:

    self.axes.plot(self.axes_plot[0], self.axes_plot[1], linewidth=2.0)
    def add_Y1(self):
        self.axes_plot[2] = self.x
        self.axes_plot[3] = self.y1
        self.axes.plot(self.axes_plot[2], self.axes_plot[3], linewidth=2.0)
        self.Canvas_plot2D.draw()