AUI and FLoatCanvas - NavCanvas

76 views
Skip to first unread message

Ricardo Marcano

unread,
Nov 13, 2009, 2:36:37 PM11/13/09
to wxpytho...@googlegroups.com
Hi, im trying to embed a FloatCanvas Graph into AUI but the canvas shows really small. I did a search in the group and I've found an advice to put everything into a sizer and create a EVT_SIZE event. I'm trying with no results and the repaint looks really slow. May be there is some update for this. All the information I got is from 3 or 4 year ago.
 
I really will appreciate if someone can give an orientation about this.
 
Thanks in advance
 
 
Ricardo

Andrea Gavana

unread,
Nov 14, 2009, 2:19:29 PM11/14/09
to wxpytho...@googlegroups.com
Hi,

2009/11/13 Ricardo Marcano:

You need to provide some more information:

- Platform, wxPython version and Python version;
- "AUI" is not enough: are you talking about wx.aui or wx.lib.agw.aui?
- Can you provide a sample app demonstrating the problem?

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/
http://thedoomedcity.blogspot.com/

rmdi

unread,
Nov 16, 2009, 10:17:40 AM11/16/09
to wxPython-users
Hi thanks for your reply. I mean the wx.aui.


please look my code i'm trying to embedd the trend class is a plot
example i've found using floatcanvas. It works but really small. I did
the same trend with buffered cambas and it works well. I think is
something related to the container's resize event but i'm trying with
no results. Im trying all this under Windows Python 2.6 and wxPython
2.8.

Thanks

This is the trend class code:

trend.py

#!/usr/bin/env python
import wx
import numpy as N
import sys
sys.path.append("../")
try:
from floatcanvas import NavCanvas, FloatCanvas, Resources
except ImportError: # if it's not there locally, try the wxPython lib.
from wx.lib.floatcanvas import NavCanvas, FloatCanvas, Resources


class TREND(wx.Window):
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, mgr=None):

wx.Window.__init__(self, parent, id, pos, size, wx.NO_BORDER)

## Set up the MenuBar
"""

MenuBar = wx.MenuBar()

file_menu = wx.Menu()
item = file_menu.Append(wx.ID_ANY, "E&xit","Terminate the
program")
self.Bind(wx.EVT_MENU, self.OnQuit, item)
MenuBar.Append(file_menu, "&File")

draw_menu = wx.Menu()
item = draw_menu.Append(wx.ID_ANY, "&Run","Run the test")
self.Bind(wx.EVT_MENU, self.RunTest, item)
item = draw_menu.Append(wx.ID_ANY, "&Stop","Stop the test")
self.Bind(wx.EVT_MENU, self.Stop, item)
MenuBar.Append(draw_menu, "&Plot")


help_menu = wx.Menu()
item = help_menu.Append(wx.ID_ANY, "&About",
"More information About this program")
self.Bind(wx.EVT_MENU, self.OnAbout, item)
MenuBar.Append(help_menu, "&Help")

self.SetMenuBar(MenuBar)
"""


#self.CreateStatusBar()
#self.SetStatusText("")

wx.EVT_CLOSE(self, self.OnCloseWindow)




# Add the Canvas
NC = NavCanvas.NavCanvas(self , wx.ID_ANY ,(200,500),
ProjectionFun = None,
Debug = 0,
BackgroundColor = "WHITE"
)
self.Canvas = NC.Canvas

self.Canvas.NumBetweenBlits = 1000

#self.AutoLayout()
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self, 1, wx.EXPAND)
self.SetSizer(sizer)
#sizer.Fit(self)
#self.Layout()
#self.Fit()
# Add a couple of tools to the Canvas Toolbar
wx.EVT_SIZE(self, self.OnRESIZE)


tb = NC.ToolBar
tb.AddSeparator()

StopButton = wx.Button(tb, wx.ID_ANY, "Stop")
tb.AddControl(StopButton)
StopButton.Bind(wx.EVT_BUTTON, self.Stop)

PlayButton = wx.Button(tb, wx.ID_ANY, "Run")
tb.AddControl(PlayButton)
PlayButton.Bind(wx.EVT_BUTTON, self.RunTest)

tb.Realize()

self.Show(True)

self.timer = None

self.DrawAxis()

return None

def OnRESIZE(self, event):
self.Layout()
def OnAbout(self, event):
dlg = wx.MessageDialog(self, "This is a small program to
demonstrate\n"
"the use of the FloatCanvas\n"
"for simple plotting",
"About Me", wx.OK |
wx.ICON_INFORMATION)
dlg.ShowModal()
dlg.Destroy()

def ZoomToFit(self,event):
self.Canvas.ZoomToBB()

def OnQuit(self,event):
self.Close(True)

def OnCloseWindow(self, event):
self.Destroy()

def DrawAxis(self):
Canvas = self.Canvas

# Draw the Axis

# Note: the AddRectangle Parameters all have sensible
# defaults. I've put them all here explicitly, so you can see
# what the options are.
#2*N.pi
self.Canvas.AddRectangle((0,0),
(3, 6),
LineColor = "Black",
LineStyle = "Solid",
LineWidth = 1,
FillColor = None,
FillStyle = "Solid",
InForeground = 0)
#Grilla
lp = N.random.rand(2,2)*0
lp[0,0] = 0.75
lp[1,0] = 0.75
lp[1,1] = 6.00
self.Canvas.AddLine(lp,
LineColor = "Gray",
LineStyle = "Solid",
LineWidth = 1,
InForeground = 1)
lp[0,0] = 1.50
lp[1,0] = 1.50
lp[1,1] = 6.00
self.Canvas.AddLine(lp,
LineColor = "Gray",
LineStyle = "Solid",
LineWidth = 1,
InForeground = 1)
lp[0,0] = 2.25
lp[1,0] = 2.25
lp[1,1] = 6.00
self.Canvas.AddLine(lp,
LineColor = "Gray",
LineStyle = "Solid",
LineWidth = 1,
InForeground = 1)
for i in range(1, 6):
lp[0,0] = 0.00
lp[0,1] = i
lp[1,0] = 3.00
lp[1,1] = i
self.Canvas.AddLine(lp,
LineColor = "Gray",
LineStyle = "Solid",
LineWidth = 1,
InForeground = 1)



""" Texto en Axis
for tic in N.arange(7):
self.Canvas.AddText("%1.1f"%tic,
(tic,-1.1),
Position = 'tc')

for tic in N.arange(-1, 1.1, 0.5):
self.Canvas.AddText("%1.1f"%tic,
(0,tic),
Position = 'cr')
"""
# Add a phantom rectangle to get the bounding box right
# (the bounding box doesn't get unscaled text right)


# No se si necesito esto
#self.Canvas.AddRectangle((-0.7, -1.5), (7, 3), LineColor =
"BLUE")

Canvas.ZoomToBB()
Canvas.Draw()

def Stop(self,event):
if self.timer:
self.timer.Stop()


def OnTimer(self,event):
self.count += .1
self.data1[:,1] = N.sin(self.time+self.count) #fake move
#rmdi
temp = self.data1[0]
#self.data2[0] = [0, 0]
#self.data2[1] = [100, 100]
tmp = [0,0]
self.data1[0] = tmp #self.data1[1]
tmp = [5,6]
self.data1[1] = tmp #temp
print "########### <<<< >>>>>> ###############"
#print type(self.data1)
#print self.data2
#rmdi
c = N.random.rand(10,1)*3
d = N.random.rand(10,1)*6
e = c + d
a = N.random.rand(100,2)*0.5
tmpi = 0.00
for i in range(0,100):
a[i,1] = tmpi
tmpi = tmpi + 0.06
a[99,1] = 6.00
#####################
b = N.random.rand(100,2)*2
tmpi = 0.00
for i in range(0,100):
b[i,1] = tmpi
tmpi = tmpi + 0.06
b[99,1] = 6.00

#a.ravel()
#a.shape(10,2)
print a
print a.shape
self.line.SetPoints(a)#self.data1)
self.line2.SetPoints(b)#self.data1)
self.Canvas.Draw()

def RunTest(self,event = None):
self.n = 100
self.dT = 0.5

self.time = 2.0*N.pi*N.arange(100)/100.0

self.data1 = 1.0*N.ones((100,2))
self.data1[:,0] = self.time
self.data1[:,1] = N.sin(self.time)
Canvas = self.Canvas
self.Canvas.ClearAll()
self.DrawAxis()
print "^^^^^^^^^^^"
print self.data1
self.line = Canvas.AddLine(self.data1,
LineColor = "Blue",
LineStyle = "Solid",
LineWidth = 1,
InForeground = 1)
self.line2 = Canvas.AddLine(self.data1,
LineColor = "Red",
LineStyle = "Solid",
LineWidth = 1,
InForeground = 1)
self.Canvas.Draw()

self.timerID = wx.NewId()
self.timer = wx.Timer(self,self.timerID)

wx.EVT_TIMER(self,self.timerID,self.OnTimer)

self.count = 0
self.timer.Start(int(self.dT*1000))



###############################################################################3


And this is the AUI frame code:


aui.py


import wx
import wx.aui
from bufferedcanvas import *
import random
import numpy as N
import sys

from TREND import TREND

# Definicion de la clase tendencia
class TendenciaCanvas(BufferedCanvas):

def __init__(self,parent,ID=-1):
BufferedCanvas.__init__(self,parent,ID)
wx.EVT_MOUSEWHEEL(self, self.OnRueda)
self.a = 0

def OnRueda(self, GETO):
self.a = self.a + GETO.GetWheelRotation()
print self.a

def draw(self, dc):
dc.SetBackground(wx.Brush("Black"))
dc.Clear()

# Bloque de codigos para simular grafico de tendencias
x1 = 0
y1 = 0
y2 = 0
x2 = 0
maximo = 300
minimo = 0
width = 300
nDat = 150
fY = 600 / nDat

dc.SetPen(wx.Pen('green', 2))

for i in range(nDat):
valor = random.randint(0,200)
x2 = round(width / (maximo - minimo) * (valor - minimo))
y2 = y2 + fY
dc.DrawLine(x1, y1, x2, y2)
x1 = x2
y1 = y2

# Integrando el metodo para generar graficos de tendencias
x1 = 0
y1 = 0
y2 = 0
x2 = 0
maximo = 300
minimo = 0
width = 300
nDat = 100
fY = 600 / nDat

dc.SetPen(wx.Pen('red', 2))

for i in range(nDat):
valor = random.randint(50,250)
x2 = round(width / (maximo - minimo) * (valor - minimo))
y2 = y2 + fY
dc.DrawLine(x1, y1, x2, y2)
x1 = x2
y1 = y2

# Fin de clase tendencia


class MyFrame(wx.Frame):

def __init__(self, parent, id=-1, title='Tiempo Real',
pos=wx.DefaultPosition, size=(800, 600),
style=wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent, id, title, pos, size, style)

self._mgr = wx.aui.AuiManager(self)
#self._mgr.SetManagedWindow(self)

# Anexando un boton
MiBoton = wx.Button(self, label="tendencia")
MiBoton.Bind(wx.EVT_BUTTON, self.ClickMiBoton)

#Sizer = wx.BoxSizer(wx.VERTICAL)
#Sizer.Add(MiBoton, 0, wx.ALIGN_CENTER|wx.ALL, 5)
#self.SetSizerAndFit(Sizer)

# create several text controls
text1 = wx.TextCtrl(self, -1, 'Pane 1 - sample text',
wx.DefaultPosition, wx.Size(200,150),
wx.NO_BORDER | wx.TE_MULTILINE)

text2 = wx.TextCtrl(self, -1, 'Pane 2 - sample text',
wx.DefaultPosition, wx.Size(200,150),
wx.NO_BORDER | wx.TE_MULTILINE)

text3 = wx.TextCtrl(self, -1, 'Pane 3 - sample text',
wx.DefaultPosition, wx.Size(200,150),
wx.NO_BORDER | wx.TE_MULTILINE)

#Sizer = wx.BoxSizer(wx.VERTICAL)
#Sizer.Add(NothingBtn, 0, wx.ALIGN_CENTER|wx.ALL, 5)
#Sizer.Add(MsgBtn, 0, wx.ALIGN_CENTER|wx.ALL, 5)


ctrl = ControlTendencia(self, -1, wx.DefaultPosition, wx.Size
(200, 200))
ctrl21 = TREND(self, -1, wx.DefaultPosition, wx.Size(200,
300))
# add the panes to the manager
self._mgr.AddPane(ctrl21, wx.RIGHT, 'Tendencia en Tiempo')
self._mgr.AddPane(text2, wx.LEFT, 'Numericos')
self._mgr.AddPane(text3, wx.CENTER,'Profundidad')
#self._mgr.AddPane(MiBoton, wx.RIGHT)
self._mgr.AddPane(ctrl, wx.RIGHT,'Tendencia')


# tell the manager to 'commit' all the changes just made
self._mgr.Update()

self.Bind(wx.EVT_CLOSE, self.OnClose)

def ClickMiBoton(self, event):
# Este metodo inicia la tendencia en tiempo
FrameTendencia = TestFrame()
FrameTendencia.Show()

def OnClose(self, event):
# deinitialize the frame manager
self._mgr.UnInit()
# delete the frame
self.Destroy()



# Size Report Control
class SizeReportCtrl(wx.PyControl):

def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, mgr=None):

wx.PyControl.__init__(self, parent, id, pos, size,
wx.NO_BORDER)

self._mgr = mgr

self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)


def OnPaint(self, event):

dc = wx.PaintDC(self)

size = self.GetClientSize()
s = ("Size: %d x %d")%(size.x, size.y)

dc.SetFont(wx.NORMAL_FONT)
w, height = dc.GetTextExtent(s)
height = height + 3
dc.SetBrush(wx.WHITE_BRUSH)
dc.SetPen(wx.WHITE_PEN)
dc.DrawRectangle(0, 0, size.x, size.y)
dc.SetPen(wx.LIGHT_GREY_PEN)
dc.DrawLine(0, 0, size.x, size.y)
dc.DrawLine(0, size.y, size.x, 0)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2))

if self._mgr:

pi = self._mgr.GetPane(self)

s = ("Layer: %d")%pi.dock_layer
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*1))

s = ("Dock: %d Row: %d")%(pi.dock_direction, pi.dock_row)
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*2))

s = ("Position: %d")%pi.dock_pos
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*3))

s = ("Proportion: %d")%pi.dock_proportion
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*4))


def OnEraseBackground(self, event):
# intentionally empty
pass


def OnSize(self, event):

self.Refresh()
event.Skip()


class ControlTendencia(wx.PyControl):
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, mgr=None):

wx.PyControl.__init__(self, parent, id, pos, size,
wx.NO_BORDER)
self._mgr = mgr

self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)


def OnPaint(self, event):


dc = wx.PaintDC(self)
dc.SetBackground(wx.Brush("Black"))
dc.Clear()

size = self.GetClientSize()
s = ("Size: %d x %d")%(size.x, size.y)
# Grafico de tendencia
# Bloque de codigos para simular grafico de tendencias
x1 = 0
y1 = 0
y2 = 0
x2 = 0
maximo = 300
minimo = 0
width = 300
nDat = 150
fY = 600 / nDat

dc.SetPen(wx.Pen('green', 2))

for i in range(nDat):
valor = random.randint(0,200)
x2 = round(width / (maximo - minimo) * (valor - minimo))
y2 = y2 + fY
dc.DrawLine(x1, y1, x2, y2)
x1 = x2
y1 = y2

# Integrando el metodo para generar graficos de tendencias
x1 = 0
y1 = 0
y2 = 0
x2 = 0
maximo = 300
minimo = 0
width = 300
nDat = 100
fY = 600 / nDat

dc.SetPen(wx.Pen('red', 2))

for i in range(nDat):
valor = random.randint(50,250)
x2 = round(width / (maximo - minimo) * (valor - minimo))
y2 = y2 + fY
dc.DrawLine(x1, y1, x2, y2)
x1 = x2
y1 = y2
#




if self._mgr:

pi = self._mgr.GetPane(self)

s = ("Layer: %d")%pi.dock_layer
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*1))

s = ("Dock: %d Row: %d")%(pi.dock_direction, pi.dock_row)
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*2))

s = ("Position: %d")%pi.dock_pos
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*3))

s = ("Proportion: %d")%pi.dock_proportion
w, h = dc.GetTextExtent(s)
dc.DrawText(s, (size.x-w)/2, ((size.y-(height*5))/2)+
(height*4))


def OnEraseBackground(self, event):
# intentionally empty
pass


def OnSize(self, event):

self.Refresh()
event.Skip()


app = wx.App()
frame = MyFrame(None)
frame.Show()
app.MainLoop()

Christopher Barker

unread,
Nov 16, 2009, 8:12:46 PM11/16/09
to wxpytho...@googlegroups.com
rmdi wrote:
> please look my code i'm trying to embedd the trend class is a plot
> example i've found using floatcanvas. It works but really small.

1) attach you code, rather than putting it straight into the email --
email clients tend to mangle it -- I couldn't run this out of the box,
and can't take the time to fix it, because:

2) make SMALL samples:

http://wiki.wxpython.org/MakingSampleApps

But from a quick look:

> class TREND(wx.Window):
> def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
> size=wx.DefaultSize, mgr=None):

...


> # Add the Canvas
> NC = NavCanvas.NavCanvas(self , wx.ID_ANY ,(200,500),
> ProjectionFun = None,
> Debug = 0,
> BackgroundColor = "WHITE"
> )

You are adding the Canvas to a wx.Window. In general, you want a
wx.Panel when you are going to put other Windows on it. It has a bunch
of features to support that.


> sizer = wx.BoxSizer(wx.HORIZONTAL)
> sizer.Add(self, 1, wx.EXPAND)
> self.SetSizer(sizer)

OK -- this is odd. You are adding self to the Sizer that is on itself?
Perhaps you intended:

sizer.Add(NC, 1, wx.EXPAND)


But I'm not sure you need the wx.Window at all -- NavCanvas is a Window,
there's no need to put it on another Window if it's going to be the only
thing there.

HTH,

-Chris

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris....@noaa.gov

rmdi

unread,
Nov 17, 2009, 8:31:07 AM11/17/09
to wxPython-users
Ok i will attach the code. i got an error last time. Maybe you can run
it.
> Chris.Bar...@noaa.gov

Ricardo Marcano

unread,
Nov 17, 2009, 8:42:29 AM11/17/09
to wxpytho...@googlegroups.com
Ok now is small so you can see only the problem. Thanks for your help. I'm a
newbie in all this.

--------------------------------------------------
From: "rmdi" <marcano...@gmail.com>
Sent: Tuesday, November 17, 2009 9:01 AM
To: "wxPython-users" <wxpytho...@googlegroups.com>
Subject: [wxPython-users] Re: AUI and FLoatCanvas - NavCanvas
TREND.py
Sample1.py

Christopher Barker

unread,
Nov 17, 2009, 12:16:45 PM11/17/09
to wxpytho...@googlegroups.com
Ricardo Marcano wrote:
> Ok now is small so you can see only the problem.

That's better. However:

There is still a bunch of extra code in there, and there was one line
that got wrapped and thus would not run. You really want to make it as
easy as possible for people to help you.

2) This is your main problem:

on line 66 of TREND.py:

you had:
sizer.Add(self, 1, wx.EXPAND)

which is adding the Window to a sizer on the window, which makes no
sense. It should be:


sizer.Add(NC, 1, wx.EXPAND)


which is what I suggested in my previous email -- do try people's
suggestions!

-Chris

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris....@noaa.gov

Ricardo Marcano

unread,
Nov 17, 2009, 2:26:00 PM11/17/09
to wxpytho...@googlegroups.com
Hi Chris I removed all the plotting stuff. I did try your sugestion but the
problem is on the container. Your plot class takes the size of the parent
but I'm unable to find where the AUI pane size is. This code works fine if I
run it from a frame. But when I add it to a AUI pane the canvas is reduced I
think to the minimal size.

Someone in the past had the same problem

http://groups.google.com/group/wxpython-users/browse_thread/thread/3748092c0b31a4a2/3b452062e1f5ab8c?lnk=gst&q=plot+aui#3b452062e1f5ab8c

I will keep trying on this.

--------------------------------------------------
From: "Christopher Barker" <Chris....@noaa.gov>
Sent: Tuesday, November 17, 2009 12:46 PM
To: <wxpytho...@googlegroups.com>
Subject: [wxPython-users] Re: AUI and FLoatCanvas - NavCanvas

>
Sample1.py

Christopher Barker

unread,
Nov 17, 2009, 3:27:07 PM11/17/09
to wxpytho...@googlegroups.com
Ricardo Marcano wrote:
> Hi Chris I removed all the plotting stuff. I did try your sugestion but the
> problem is on the container. Your plot class takes the size of the parent

Actually, it takes the size you want it -- you would do that if you want
the container to fit it.

In this case, it expands to fit its container.

What you were missing is a call to SetSizer(), so that the sizer would
get used!

It also helped to give the TREND panel a size on initialization, though
I'm still confused as to why the text widget is so big -- but I think
that's an AIU question!

See my edited version enclosed.

-Chris
Sample1.py

Ricardo Marcano

unread,
Nov 17, 2009, 4:04:12 PM11/17/09
to wxpytho...@googlegroups.com
Man it works!! Really Thanks!!! I checked the first version and I've found
SetSizer commented. All is working as expected. Thanks again. I can't
believe that the solution was so simple. That happens to rookies like me.

--------------------------------------------------
From: "Christopher Barker" <Chris....@noaa.gov>
Sent: Tuesday, November 17, 2009 3:57 PM

Christopher Barker

unread,
Nov 17, 2009, 4:46:54 PM11/17/09
to wxpytho...@googlegroups.com
Ricardo Marcano wrote:
> Man it works!! Really Thanks!!! I checked the first version and I've found
> SetSizer commented. All is working as expected.

I'm glad you got it working.

Please feel free to send and FloatCanvas specific questions to:

http://mail.paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas

Reply all
Reply to author
Forward
0 new messages