当前位置: 首页 > 知识库问答 >
问题:

matplotlib wxpython没有正确调整大小与传说

高展
2023-03-14

我有一个matplotlib图,嵌入了一个wxpython框架中,带有一些尺寸标注器。在我加入一个传奇之前,一切都很好,但随后施胶器似乎没有与传奇一起工作。

即使通过在拐角处拖动来调整窗口的大小,主图形也会改变大小,但只会显示图例的边缘。

也就是说,请注意,图例在wxFrame中不可见。

import wx
import matplotlib as mpl
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
from random import shuffle  

class PlotFrame(wx.Frame):

    def __init__(self):     

        wx.Frame.__init__(self, None, -1, title="Plot", size=(-1, -1))
        self.main_panel = wx.Panel(self, -1)
        self.plot_panel = PlotPanel(self.main_panel)

        s0 = wx.BoxSizer(wx.VERTICAL)
        s0.Add(self.main_panel, 1, wx.EXPAND)
        self.SetSizer(s0)
        self.s0 = s0

        self.main_sizer = wx.BoxSizer(wx.VERTICAL)        
        self.main_sizer.Add(self.plot_panel, 1, wx.EXPAND)        
        self.main_panel.SetSizer(self.main_sizer)       

class PlotPanel(wx.Panel):

    def __init__(self, parent, id = -1, dpi = None, **kwargs):
        wx.Panel.__init__(self, parent, id=id, **kwargs)
        self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2,2))
        self.canvas = Canvas(self, -1, self.figure)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas,1,wx.EXPAND)
        self.SetSizer(sizer)
        sizer.SetMinSize((600, 500))
        self.sizer = sizer

def test(plot_panel):
    axes = plot_panel.figure.gca()
    for c in ['r', 'b', 'k']:
        vals = [20, 30, 40, 50, 80, 20, 50, 60, 70, 70, 80]
        shuffle(vals)
        axes.plot(range(len(vals)), vals, "-o", color=c, label=c*10)
    legend = axes.legend(loc='center left', bbox_to_anchor=(1.05, 0.5))
    return legend

if __name__=="__main__":
    app = wx.PySimpleApp()
    frame = PlotFrame()
    legend = test(frame.plot_panel)
    frame.Fit()
    print "legend frame pre show: ", legend.get_frame()
    frame.Show(True)
    print "legend frame post show:", legend.get_frame()
    frame.Fit()
    app.MainLoop()

编辑:
对于对我有用的解决方案,我希望它在程序自动绘制图形时看起来很好,这样调整参数可以在程序中硬编码,或者,例如,在窗口调整事件中,但不能为每个绘图手动调整。我希望在这里更改的主要内容是:1)标签的长度(例如,从1到25个字符),2)窗口大小(通常由用户在拐角处拖动,以及3)点和线的数量。(另外,如果有关系的话,我最终会希望在底轴上标注日期。)

我已经把图例放在轴之外,这样它就不会覆盖任何数据点,我更喜欢它留在轴的右边。

我正在使用Python 2.6。6,wxPython 2.8。12.1和matplotlib 1.1。0,我现在只能用这些了。

共有1个答案

景英杰
2023-03-14

它正在正确调整大小,您只是没有告诉它做您希望它做的事情。

问题在于这一行:

axes.legend(loc='center left', bbox_to_anchor=(1.05, 0.5))

非常确定的bbox_to_anchorkwarg是过度清除lockwarg,您将图例的左下角与(1.05,0.5)轴单位挂钩。如果轴展开以填满您的窗口,图例的左边缘将始终是轴右边缘右侧宽度轴的5%,因此总是看不见。

你要么需要把你的传奇放在其他地方,要么缩小你的轴(在数字分数中)。

axes.legend(bbox_to_anchor=(0.5, 0.5)) #find a better place this is in the center
axes.set_position([.1, .1, .5, .8]) # units are in figure fraction

设置位置

fig = figure()
axes = fig.add_subplot(111)

for c in ['r', 'b', 'k']:
    vals = [20, 30, 40, 50, 80, 20, 50, 60, 70, 70, 80]
    shuffle(vals)
    axes.plot(range(len(vals)), vals, "-o", color=c, label=c*10)

legend = axes.legend(loc='center left', bbox_to_anchor=(1.05, 0.5))
# adjust the figure size (in inches)
fig.set_size_inches(fig.get_size_inches() * np.array([1.5, 1]), forward=True)

# and the axes size (in figure fraction)
# to (more-or-less) preserve the aspect ratio of the original axes
# and show the legend
pos = np.array(axes.get_position().bounds)
pos[2] = .66
axes.set_position(pos)
fig = figure() # use plt to set this up for demo purposes
axes = fig.add_subplot(111) # add a subplot

# control paramters 
left_pad = .05 
right_pad = .05

# plot data
for c in ['r', 'b', 'k']:
    vals = [20, 30, 40, 50, 80, 20, 50, 60, 70, 70, 80]
    shuffle(vals)
    axes.plot(range(len(vals)), vals, "-o", color=c, label=c*10)
# set axes labels
axes.set_xlabel('test x')
axes.set_ylabel('test y')

# make the legend
legend = axes.legend(loc='center left', bbox_to_anchor=(1 + left_pad, 0.5))

# function to 'squeeze' the legend into place
def squeeze_legend(event):
    fig.tight_layout()
    right_frac = 1 - legend.get_window_extent().width / fig.get_window_extent().width - left_pad - right_pad
    fig.subplots_adjust(right=right_frac)
    fig.canvas.draw()

# call it so the first draw is right
squeeze_legend()

# use the resize event call-back to make sure it works even if the window is re-sized
fig.canvas.mpl_connect('resize_event', squeeze_legend)
 类似资料:
  • 编辑:它现在可以工作了,我用画布扩展了这个类,将它的大小设置为宽度和高度,然后将它添加到JFrame,然后打包。这管用!但我认为造成这种情况的原因不是尺寸大小,而是我呈现它的方式,我从JFrame中获得了bufferStrategy,而不是画布,这不是应该的方式。

  • 我正在使用此库:https://github.com/yshrsmz/KeyboardVisibilityEvent检测键盘何时打开或关闭,这取决于android清单的输入。 此库可以完美地检测软键盘的打开和关闭事件,但由于adjustResize参数,我的内容被推到了视图之外。 > Java: XML: 因此,通过调整第二个编辑文本的行,这非常有效,因此我在键盘上方键入,但当我关闭键盘时,滚动到

  • 问题内容: 我在Java中使用Apache POI创建一个Excel文件。我填写了数据,然后尝试自动调整每列的大小,但是大小总是错误的(我 认为是 一致的)。前两行始终(?)完全折叠。当我在excel中自动调整列的大小时,它可以完美运行。 (我相信)没有空白单元被写入,并且调整大小是我要做的 最后一 件事。 这是相关的代码: 这是一个精简的版本,没有错误处理等。 我知道那里有一些类似的问题,但是其

  • 我似乎无法调整这个iframe的大小 为了简单起见,我没有包括几个包装div,因为它们只用于样式。然而,上面的两个外部div位于flexbox的div中,因此它们是水平显示的,而不是占据整个水平空间。我将内容div设置为100%的宽度,第一个div设置为固定宽度。如你所见,iframe也从硬编码的固定宽度/高度开始。还要注意,重置iframe的src在js函数中起作用,而不是宽度和高度。 谢谢你

  • 我一直在尝试学习按钮,但它拒绝调整大小。按钮1(下面的代码)只占据了整个屏幕。我看到其他帖子的问题是他们没有使用 但是我正在使用它,它仍然不工作!我还没有制作JPanel。这是我的JFrame: 我的主要课程简单明了:

  • 你好,谢谢你花时间处理我的问题。首先让我向你介绍我的虚拟/培训项目。下面列出的类应该代表MVC模型(模型、视图、控制器)之后的程序。运行主类时,会打开FileChooser,从中可以选择. csv-File,其中包含保存为String[][]的信息。这个String[][]然后在视图类中可视化为JTable。这个JTable是带有BorderLayout的JFrame中的JPanel的一部分。中心