(wx.lib.plot) PlotCanvas does not update itself

I adjust the objects in the plot dynamically, but it only applies when the frame has been resized manually by mouse dragging.
I had got a similar problem long before and Refresh(), Update(), or something was helpful at that time as I remember and the old posts says. But it is not working now.
Here is the simplified code that adds and removes a marker by button clicked. As you can see, you have to resize the frame to see the change. (Only the first addition is shown immediately as you add)

How can I force update?

Windows 10
Python 3.9.6
wxPython 4.1.1

import wx
import numpy as np
from wx.lib.plot import PlotCanvas, PlotGraphics, PolyMarker

class myframe(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None)

        self.panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.x = []
        self.y = []
        self.marker = PolyMarker([])
        self.graphics = PlotGraphics([self.marker])
        self.canvas = PlotCanvas(self.panel)
        self.canvas.Draw(self.graphics, xAxis=(-1, 11), yAxis=(-1, 11))

        sizer_btn = wx.BoxSizer(wx.HORIZONTAL)

        self.btn1 = wx.Button(self.panel, label='Add')
        self.btn1.Bind(wx.EVT_BUTTON, self.add)
        sizer_btn.Add(self.btn1, 0, wx.ALL, 3)

        self.btn2 = wx.Button(self.panel, label='Remove')
        self.btn2.Bind(wx.EVT_BUTTON, self.remove)
        sizer_btn.Add(self.btn2, 0, wx.ALL, 3)

        sizer.Add(self.canvas, 1, wx.EXPAND)
        sizer.Add(sizer_btn, 0, wx.ALIGN_RIGHT)

    def add(self, e):

    def remove(self, e):
        if len(self.x) >= 1:

    def my_redraw(self):
        points = np.array([self.x, self.y]).transpose().tolist()
        self.marker.points = points

        # Option 1 ------------
        # ---------------------

        # Option 2 ------------
        # self.canvas.Clear()
        # self.canvas.Draw(self.graphics, xAxis=(0, 10), yAxis=(0, 10))
        # ---------------------

        # Nothing worked here ---------------------
        # self.canvas.Refresh()
        # self.canvas.Update()
        # self.canvas.Layout()
        # self.panel.Refresh()
        # self.panel.Update()
        # self.panel.Layout()
        # self.Refresh()
        # self.Update()
        # self.Layout()
        # -----------------------------------------

if __name__ == '__main__':
    app = wx.App()
    frame = myframe()

The fun part is that not even “self.canvas.Redraw” is necessary to the (non-)functioning of your example. If you comment it out, you’ll see that your code will work just the same. So, apparently “Redraw” does not redraws at all, at least not the way it’s supposed to.
The frustrating part is that the canvas won’t respond to a “SendSizeEvent()” either, a trick that usually works in such cases.
Now, from a cursory glance at the code of the examples, it looks like wx.lib.plot is intended for “static” plots only, and there are no hooks for updating “on the fly” an already existing graph. Of course, nothing stops you from erasing all the content and start over… but if you need frequent updates (say, a “live” graphic plotting from a data stream) then you will end up with some flickering I’m afraid.
You should probably dig in the source code and find out what exactly happens in response to a EVT_SIZE (since this is when your plot get updated, apparently) and see if you can trigger the same thing on demand. And while you’re at it, perhaps also take a look at that “Redraw” thing, and figure out what it really does.

omg, it is true that I even don’t need “Redraw().”
I will look into EVT_SIZE as you mentioned.
By the way, do you have any recommended sight-package for ‘live’ plotting? I use Matplotlib usually but it it not good for live at all.

Not sure what you need for “live” plotting, but I’ve discovered a way to make “oscilloscope” type plots with Matplotlib with fairly rapid re-plotting. Here’s an example:
oscope.py (473 Bytes)
This runs pretty fast on my machine using the WxAgg backend.