Hi Guys,

I am trying to draw on PlotCanvas using wx.DC module. I have several problems with drawing on WXBufferedPaintDC, for some reason my DC text disappears after windows resizing and it looks that I draw my text in the wrong place. Any help appreciated. Here is my code:

import wx
import wx.lib.plot as plot
USE_BUFFERED_DC = True
class MyFrame(wx.Frame):
   def __init__(self):
      wx.Frame.__init__(self, None, id=-1, title="Graph display", size=(1000,1000))
      main_panel = wx.Panel(self, -1)
      #data for the plot
      data = [[1,5],[2,4],[3,8],[4,3],[5,2]]
      line = plot.PolyLine(data, colour='red', width=1)
      #plot window & bindings
      self.plot_window = plot.PlotCanvas(main_panel, -1)
      gc = plot.PlotGraphics([line], 'y-axis', 'x-axis', 'Title')
      self.plot_window.Draw(gc)
      self.plot_window.canvas.Bind(wx.EVT_LEFT_DOWN, self.mouseleftdown)
      self.plot_window.canvas.Bind(wx.EVT_PAINT, self.Paint)
      self.buffer = wx.EmptyBitmap(500, 500)  # draw to this
      dc = wx.BufferedDC(wx.PaintDC(self.plot_window.canvas), self.buffer)
      vbox_sizer = wx.BoxSizer(wx.VERTICAL)
      vbox_sizer.Add(self.plot_window, 1, wx.EXPAND|wx.ALIGN_LEFT)
      main_panel.SetAutoLayout(True)
      main_panel.SetSizer(vbox_sizer)
      main_panel.Layout()

   def mouseleftdown(self, event):
      x, y = event.GetPosition()
      print "Left Mouse Down at Point:", x, y
      dc = wx.BufferedDC(wx.PaintDC(self.plot_window.canvas), self.buffer)
      dc.Clear()  # black window otherwise
      dc.DrawText("SomeText", x, y)
   def Paint(self, event):
        if USE_BUFFERED_DC:
            dc = wx.BufferedPaintDC(self, self.buffer)
        else:
            dc = wx.PaintDC(self)
            dc.DrawBitmap(self.buffer, 100, 100)
        self.UpdateDrawing()

   def UpdateDrawing(self):
        dc = wx.MemoryDC()
        dc.SelectObject(self.buffer)
        del dc # need to get rid of the MemoryDC before Update() is called.
        self.Refresh()
        self.Update()



app = wx.PySimpleApp()
MyFrame().Show()
app.MainLoop() 

Recommended Answers

All 4 Replies

Have not used wxPython ever since Python3 came out.
I still have Portable Python276 on my flashdrive and found this.

Have you tried wxPython's wx.lib.plot.PlotCanvas()?
Here is an example ...

# using wxPython's wx.lib.plot.PlotCanvas()
# to show a line graph of some trig functions
# also save graph to an image file
# vega

import wx
import wx.lib.plot
import math

class MyFrame(wx.Frame):
    def __init__(self, parent, mytitle, mysize):
        wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle, size=mysize)

        # calculate data lists of (x, y) tuples
        # x is in radians
        sin_data = []
        cos_data = []
        x = 0
        while True:
            y = math.sin(x*x)
            sin_data.append((x, y))
            y = math.sin(x*x) + math.cos(x**0.5)
            cos_data.append((x, y))
            x += 0.01
            if x > 4*math.pi:
                break

        # set up the plotting canvas
        plot_canvas = wx.lib.plot.PlotCanvas(self)
        # get client usable size of frame
        frame_size = self.GetClientSize()
        # needed for SaveFile() later
        plot_canvas.SetInitialSize(size=frame_size)
        # optional allow scrolling
        plot_canvas.SetShowScrollbars(True)
        # optional drag/draw rubberband area to zoom
        # doubleclick to return to original
        # right click to shrink
        plot_canvas.SetEnableZoom(True)
        # optional
        # set the tick and axis label font size (default is 10 point)
        plot_canvas.SetFontSizeAxis(point=8)
        # set title font size (default is 15 point)
        plot_canvas.SetFontSizeTitle(point=10)

        # connect (x, y) points in data list with a line
        sin_lines = wx.lib.plot.PolyLine(sin_data, colour='red', width=1)
        cos_lines = wx.lib.plot.PolyLine(cos_data, colour='blue', width=1)

        # assign lines, title and axis labels
        gc = wx.lib.plot.PlotGraphics([sin_lines, cos_lines],
            'red=sin(x*x)   blue=sin(x*x) + cos(x**0.5)',
            'X Axis (radians)', 'Y Axis')
        # draw the plot and set x and y axis sizes
        plot_canvas.Draw(gc, xAxis=(0, 7), yAxis=(-2, 2))

        # optional save graph to an image file
        plot_canvas.SaveFile(fileName='trig1.jpg')


app = wx.App(0)
# create a MyFrame instance and show the frame
caption = "wx.lib.plot.PlotCanvas() Line Graph"
MyFrame(None, caption, (400, 300)).Show()
app.MainLoop()

Thank you for your reply. This is exactly what I am using.
import wx.lib.plot as plot
self.plot_window = plot.PlotCanvas(main_panel, -1)
My problem with keeping wx.DC object on wx.lib.plot.PlotCanvas after windows refresh.

Is there something new in Python3 which allows you to do something similar?

thank you in advance!

As far as I know wxPython is slowly patched onto Python3. I have not checked it lately. Some of the problems you encountered may have been corrected.

I see, thank you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.