2015-01-19 7 views
0

Я пытаюсь сделать wx.Notebook с фигурой на каждой странице и уникальными цифрами/осями на этих холстах. Проблема в том, что если размер фигуры (по fig.set_size_inches) равен поплавка до 2 или более знаков после запятой, цифры на разных страницах будут слегка перекрываться друг с другом. Я не могу понять, почему это происходит и как это исправить.Как разбить несколько холстов в wx.Notebook, выдать с размерами float и перекрытием (WxPython, Matplotlib)

Чтобы увидеть проблему перекрытия, вы должны перейти на вкладку 2, а затем вернуться к вкладке 1, а перекрытие появится в нижней части первого графика.

Picture of what I'm talking about

import wx 

# Import Matplotlib 
from matplotlib.figure import Figure 
import matplotlib.pyplot as plt 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas 

class MyFrame (wx.Frame): 

    def __init__(self, parent): 

     # FORM BUILDER OUTPUT 
     ######################### 
     wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(600,500), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 

     self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 

     bSizer9 = wx.BoxSizer(wx.VERTICAL) 

     self.m_notebook2 = wx.Notebook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0) 
     self.m_panel5 = wx.Panel(self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer10 = wx.BoxSizer(wx.VERTICAL) 

     self.m_panel5.SetSizer(bSizer10) 
     self.m_panel5.Layout() 
     bSizer10.Fit(self.m_panel5) 
     self.m_notebook2.AddPage(self.m_panel5, u"Page1", False) 
     self.m_panel6 = wx.Panel(self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer11 = wx.BoxSizer(wx.VERTICAL) 

     self.m_panel6.SetSizer(bSizer11) 
     self.m_panel6.Layout() 
     bSizer11.Fit(self.m_panel6) 
     self.m_notebook2.AddPage(self.m_panel6, u"Page2", False) 

     bSizer9.Add(self.m_notebook2, 1, wx.EXPAND |wx.ALL, 5) 

     self.SetSizer(bSizer9) 
     self.Layout() 

     self.Centre(wx.BOTH) 

     ######################### 

     graph1 = self.create_graph(self.m_panel5, size=(3, 2.255252)) 
     graph2 = self.create_graph(self.m_panel6, size=(5.5556, 3.5)) 

     #################### 

    def create_canvas(self, panel, size): 
     fig = Figure() 
     ax = fig.add_subplot(111) 
     ax.set_xlim([0,10]) 
     ax.set_ylim([0,100]) 
     ax.axis('off') 

     fig.set_size_inches(size) # If this is a float to 3 decimals is causes problems 

     canvas = FigureCanvas(panel, -1, fig) 
     sizer = panel.GetSizer() 
     sizer.Add(canvas) 
     return(canvas) 

    def create_graph(self, panel, size): 
     canvas = self.create_canvas(panel,size) 
     ax = canvas.figure.axes[0] 
     xdata = range(1,10) 
     ydata = [x*x for x in xdata] 
     ax.scatter(xdata, ydata) 
     ax.bar(xdata, [100]*9, 0.5, 0, color='red') 
     ax.plot() 
     return(ax) 


class MyApp(wx.App): 
    def OnInit(self): 
     main = MyFrame(None) 
     main.Show() 
     return True 

app = MyApp(0) 
app.MainLoop() 

print('Done') 
+0

Я не вижу такого поведения на Xubuntu. Какую ОС и версию wxPython вы используете? –

+0

Ах должно было это упомянуть. Windows 7 с wxPython 2.8 (['2.8-msw-unicode']) – user3294935

ответ

0

Пытался код на Windows (WxPython 2.9.5.1/mpl 1.3.1) и получил тот же результат (красные отметины на нижней части первого участка).

Я бы решил проблему, но по-другому, и укажите размер сюжета не в matplotlib, а в wxPython.

При изменении кода следующим образом:

def __init__(self, parent): 
    ... 
    graph2 = self.create_graph(#... 
    self.Layout() # put this at the end 

def create_canvas(self, panel, size): # size can be omitted 
    fig = Figure(dpi=96) # specify the dpi instead of the size 
    ... 
    # comment this out 
    # fig.set_size_inches(size) 

все рисуется правильно и проклейки имеет больше смысла.

EDIT: возник вопрос о том, как иметь фиксированное соотношение сторон для холста mpl без указания размера в дюймах. Вы можете использовать wx.SHAPED флаг вместо wx.EXPAND при добавлении к классификатору и писать

bSizer9.Add(self.m_notebook2, 1, wx.SHAPED |wx.ALL, 5) 

который будет держать соотношение сторон, как обращен в __init__.

+0

Ага спасибо! Мне нравится это решение. Я раньше не работал с dpi, есть ли способ с wxpython, чтобы я мог контролировать соотношение сторон фигуры? Важно иметь отношение высоты/ширины как определенное значение, поэтому я раньше возился с поплавками в set_size_inches. – user3294935

+0

Интересный вопрос, см. Править выше. Хотя я не получил «принять», я все еще узнал что-то новое из этого вопроса. – nepix32

0

Одним из способов решения проблемы является вызов метода Layout() страницы при каждом переходе между страницами. Вот пример, который работал для меня в Windows 7 с помощью wxPython 3 и Python 2.7:

import wx 

# Import Matplotlib 
from matplotlib.figure import Figure 
import matplotlib.pyplot as plt 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas 

class MyFrame (wx.Frame): 

    def __init__(self, parent): 

     # FORM BUILDER OUTPUT 
     ######################### 
     wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(600,500), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 

     self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 

     bSizer9 = wx.BoxSizer(wx.VERTICAL) 

     self.m_notebook2 = wx.Notebook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0) 
     self.m_notebook2.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onPageChanged) 
     self.m_panel5 = wx.Panel(self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer10 = wx.BoxSizer(wx.VERTICAL) 

     self.m_panel5.SetSizer(bSizer10) 
     self.m_panel5.Layout() 
     bSizer10.Fit(self.m_panel5) 
     self.m_notebook2.AddPage(self.m_panel5, u"Page1", False) 
     self.m_panel6 = wx.Panel(self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer11 = wx.BoxSizer(wx.VERTICAL) 

     self.m_panel6.SetSizer(bSizer11) 
     self.m_panel6.Layout() 
     bSizer11.Fit(self.m_panel6) 
     self.m_notebook2.AddPage(self.m_panel6, u"Page2", False) 

     bSizer9.Add(self.m_notebook2, 1, wx.EXPAND |wx.ALL, 5) 

     self.SetSizer(bSizer9) 
     self.Layout() 

     self.Centre(wx.BOTH) 

     ######################### 

     graph1 = self.create_graph(self.m_panel5, size=(3, 2.255252)) 
     graph2 = self.create_graph(self.m_panel6, size=(5.5556, 3.5)) 

     #################### 

    def create_canvas(self, panel, size): 
     fig = Figure() 
     ax = fig.add_subplot(111) 
     ax.set_xlim([0,10]) 
     ax.set_ylim([0,100]) 
     ax.axis('off') 

     fig.set_size_inches(size) # If this is a float to 3 decimals is causes problems 

     canvas = FigureCanvas(panel, -1, fig) 
     sizer = panel.GetSizer() 
     sizer.Add(canvas) 
     return(canvas) 

    def create_graph(self, panel, size): 
     canvas = self.create_canvas(panel,size) 
     ax = canvas.figure.axes[0] 
     xdata = range(1,10) 
     ydata = [x*x for x in xdata] 
     ax.scatter(xdata, ydata) 
     ax.bar(xdata, [100]*9, 0.5, 0, color='red') 
     ax.plot() 
     return(ax) 

    def onPageChanged(self, event): 
     self.m_panel5.Layout() 
     self.m_panel6.Layout() 


class MyApp(wx.App): 
    def OnInit(self): 
     main = MyFrame(None) 
     main.Show() 
     return True 

app = MyApp(0) 
app.MainLoop() 
+0

Когда я использую EVT_NOTEBOOK_PAGE_CHANGED, размеры двух графиков не отличаются друг от друга (нет изменений с одной вкладки на другую. Вы тоже это видите? Я также пробовал EVT_NOTEBOOK_PAGE_CHANGING, что делает разные размеры, но тогда проблемы перекрытия остаются. – user3294935

+0

Нет, нет. Графы все еще разных размеров, но перекрытия там нет. Может быть, это может быть разница между wx 2.8 и wx 3.0? –

+0

Обновлено до 3.0, и все работает плавно. разочаровывает меня до конца. Могут быть некоторые цели, которые нужно исправить сейчас, когда я использую 3.0, но я сомневаюсь, что это будет почти так же запутанно, как это было ... – user3294935