简体   繁体   中英

Dynamically update graphics in matplotlib

# when the code works but it's meaningless to include it
### When I can't get this part to work and I'd need your code

How do you hide or show an Axes object (subplot) in matplotlib so you can toggle between different Axes in the same figure?

I'm using matplotlib to display graphics in a Tkinter GUI and I'd like to use radiobuttons to switch between different axes in the same figure.

Basically I'll have some radiobuttons linked to a IntVar():

graphic_version = tk.IntVar()
tk.Radiobutton(root, text='Option1', variable=graphic_version, value=1).pack()
tk.Radiobutton(root, text='Option2', variable=graphic_version, value=2).pack()

Then I'd trace the IntVar() with a custom methods updating my figure with the requested graphic:

choice.trace("w", lambda choice: myGraphic.showGraphic(version))

so that everytime the user clicks a radiobutton the figure is updated with a different version of the plot. Now the problem is I have no idea how to do the showGraphic properly. Lets say I use this class system to get 2 different versions of plotting the same data:

class Version1():
    def __init__(self, ax, data):
        self.ax = ax #This is a Axes object
        self.data = self._formatDataV1(data)

        self._draw()
        self._setOptions()
        self.hide()

    def _formatDataV1(self, data):
        #Here I manipulate the raw data to extract the info I need for this version
        #Just a bunch of math algorithms it works fine

    def _setOptions(self):
        #Here I can overwrite or change settings specific for this version

    def _draw(self):
        self.ax.bar(self.data[0], self.data[1], width=1, color='red')
        self._setOptions()

    def hide(self):
        ###How do I remove the ax without affecting the figure?

    def show(self):
        ###If I want to see this version again I don't want the cost of redrawing   


class Version2():
    def __init__(self, ax, data):
        self.ax = ax #This is a Axes object
        self.data = self._formatDataV1(data)

        self._draw()
        self._setOptions()
        self.hide()

    def _formatDataV2(self, data):
        #The data is manipulated differently here to extract new information

    def _setOptions(self):
        #These options are specific to the version2 to get the display right

    def _draw(self): #Drawing a different version of the graphic with differently formated data
        self.ax.plot(self.data[0], self.data[1])
        self._setOptions()

    def hide(self):
        ###How do I remove the ax without affecting the figure?

    def show(self):
        ###If I want to see this version again I don't want the cost of redrawing

class MyGraphic(tk.LabelFrame):
    def __init__(self, root, data, **options):
        #I use the labelframe only as a container to make things pretty
        tk.LabelFrame.__init__(self, root, text="My 1337 graphic : ", **options)

        self.data = data
        self.fig = mpl.figure.Figure()
        self.ax = self.fig.add_subplot(111)

        self._drawCanvas() #This is just for Tkinter compatibility

        self.my_versions = {}
        self.my_versions.update({'v1' : Version1(self.ax, self.data)})
        self.my_versions.update({'v2' : Version2(self.ax, self.data)})

    def _drawCanvas(self):
        self.canvas = FigureCanvasTkAgg(self.figure, master=self)
        self.canvas.show()
        self.canvas.get_tk_widget().grid()
        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    def _setOptions(self, **kwargs):
        #Here I can set options common to both versions of the graphic

    def showGraphic(self, graphic_version):
        for i, item in enumerate(self.my_versions):
            item.hide()
        if graphic_version == 1:
            self.my_versions['v1'].show()
        elif graphic_version == 2:
            self.my_versions['v2'].show()

        self._setOptions()

Sorry for the lengthy post but I rather include too many details and edit out those who are not necessary when it's solved.

Basically I want to be able to hide and show different ax on the same figure depending on the choice made by my user. The missing parts of the puzzle are myGraphic.show() and myGraphic.hide().

I'm also a complete matplotlib newby I tried this design because it seemed clear and easy to implement additional versions when needed but design inputs are also really appreciated.

您可以使用fig.delaxes(并使用add_axes添加)从图形中删除轴: http ://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.delaxes

我设法用figure.clear()figure.add_axes(ax)解决了这个问题,明天我将尝试编辑一个干净的问题-答案,其中有一个最小的示例,说明如何在同一图上切换不同版本的绘图图在Tkinter。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM