Mr. Who
Mr. Who

Reputation: 189

Updating the color of embeded matplotlib plot in tkinter

I tried to put some option for embedded matplotlib plot in tkinter. The style of plot (i.e. solid line or dashed line) changes properly but the color does not. However, by resizing the tkinter window the color got updated. The related part of my code is demonstrated below:

import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from tkinter.colorchooser import askcolor
import numpy as np



class Ploter:
    DEFAULT_PEN_SIZE = 5.0
    DEFAULT_COLOR = 'black'
    DEFAULT_STYLE = '-'
    def __init__(self, master, size = (5,4), dpi = 100):
        self.master = master
        self.size = size
        self.dpi = dpi
        self.color = self.DEFAULT_COLOR
        self.style = self.DEFAULT_STYLE
        self.fig = Figure(figsize = self.size, dpi=self.dpi)
        self.canvas = FigureCanvasTkAgg(self.fig , master=self.master)
        self.ax = self.fig.add_subplot(111)
        self.t = np.arange(0, 3, 0.01)
        self.tf = 2 * np.sin(2 * np.pi * self.t)

    def PlotWidgets(self):

        toolbar = NavigationToolbar2TkAgg(self.canvas, self.master)
        toolbar.update()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)



        list1 = ["Solid", "Dashed", "Dash-dot", 'Dotted'] 
        self.line_style = tk.StringVar()
        self.line_style.set('Line Style')
        self.line_style.trace("w", self.choose_style)
        droplist = tk.OptionMenu(self.master, self.line_style, *list1)
        droplist.config(width=10)
        droplist.pack(side = tk.LEFT , padx = 10 , pady = 10)

        color_button = tk.Button(master = self.master, text='color',
                                 command = self.choose_color)
        color_button.pack(side = tk.LEFT , padx = 10 , pady = 10)

        self.ploter()

    def ploter(self):
        self.ax.clear()
        style = self.style
        self.ax.plot(self.t, self.tf, style , color = self.color)
        self.canvas.draw()


    def choose_color(self):
        style = self.style
        self.color = askcolor(color=self.color)[1]
        self.ax.plot(self.t, self.tf, style , color = self.color)
        #self.canvas.draw()
    def choose_style(self, * args):
        if self.line_style.get() == "Solid":
            self.style = '-'
            self.ploter()
        if self.line_style.get() == "Dashed":
            self.style = '--'
            self.ploter()
        if self.line_style.get() == "Dash-dot":
            self.style = '-.'
            self.ploter()
        if self.line_style.get() == "Dotted":
            self.style = ':'
            self.ploter()




root = tk.Tk()
root.wm_title("Embedding in tkinter")
pp = Ploter(root)
pp.PlotWidgets()
root.mainloop()

I have tried rebooting the computer, different IDE or running the script from terminal, and none of them remedy the situation.

It is worth to mention that I am using Linux mint 19.2 (MATE desktop, x11 display server), python 3.6.8, matplotlib 2.1.1, tkinter 8.6.

Upvotes: 0

Views: 394

Answers (1)

Henry Yik
Henry Yik

Reputation: 22503

Add canvas.draw_idle() to both your ploter and choose_color func:

def ploter(self):
    self.ax.clear()
    style = self.style
    self.ax.plot(self.t, self.tf, style , color = self.color)
    self.canvas.draw_idle()

def choose_color(self):
    style = self.style
    self.color = askcolor(color=self.color)[1]
    self.ax.plot(self.t, self.tf, style , color = self.color)
    self.canvas.draw_idle()

Upvotes: 1

Related Questions