0

I’m using matplotlib in wxpython, and here is what I’m trying to do…

I’d like to define my figure to be a specific (user chosen) size…say 8 inches wide by 6 inches high.

Then, I’d like the user to be able to size the window and resize/scale the plot to fit the window, but the underlying figure still be 8x6 (to ensure fonts stay the right size and such).

What I’m currently doing is this:

    size = self.GetClientSize()
    self.canvas.SetSize(size)
    self.figure.set_size_inches(8, 6)
    self.figure.set_dpi(min(size.width/8, size.height/6))
    # my plot configuration code is here
    self.canvas.draw_idle()

This works great from a sizing standpoint, but if you size up the plot and back down, I end up with clutter on the right or bottom. Like this:

enter image description here

Any suggestions? I saw something about wxDC.SetLogicalScale, but couldn’t figure out how to get a DC or how to custom paint the background.

1 Answer 1

0

Should it keep the exact size of 8x6 inches or the width to height ratio as 8 to 6?

If it's the former, wouldn't it work to put it in the center of a 3x3 FlexGridSizer and make all cells except the central one growable? You didn't provide a minimal reproducible example, showing what you're drawing and how, so I made my own, loosely based on the first example from here:

from numpy import arange, sin, pi
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import wx

class MyCanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, size=(800, 600))

        self.figure = Figure()
        self.figure.set_size_inches(8, 6)
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)

        sizer = wx.FlexGridSizer(3, 3, 0, 0)
        for i in range(4): sizer.AddStretchSpacer()
        sizer.Add(self.canvas, 1, wx.EXPAND)
        for i in range(4): sizer.AddStretchSpacer()
        
        sizer.AddGrowableRow(0, 1)
        sizer.AddGrowableRow(2, 1)
        sizer.AddGrowableCol(0, 1)
        sizer.AddGrowableCol(2, 1)
        
        self.SetSizer(sizer)
        self.Fit()

    def Draw(self):
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)


class MyFrame(wx.Frame):
    def __init__(self, title):
        wx.Frame.__init__(self, None, -1, title, size=(800, 600))

        self.panel = MyCanvasPanel(self)
        self.panel.Draw()


class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame("8x6 inches")
        self.SetTopWindow(frame)
        frame.Show(True)

        return True


if __name__ == "__main__" :
    app = MyApp(False)
    app.MainLoop()

If it's the latter - the plot should grow and shrink, but proportionally - then wouldn't it work to simply set aspect to 'equal' with matplotlib, e. g.:

class MyCanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.axes.set_aspect('equal', 'box')
        self.canvas = FigureCanvas(self, -1, self.figure)

        sizer = wx.BoxSizer()
        sizer.Add(self.canvas, 1, wx.EXPAND)
        
        self.SetSizer(sizer)
        self.Fit()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.