Colorbar embedding in qt4

Hi, I have a scatter plot embedded in qt4 according to http://matplotlib.sourceforge.net/examples/user_interfaces/embedding_in_qt4.html what works fine
However if I try to add a colorbar to it by simply calling

p = scatter(…)
colorbar§

I get an error that says that something is outside the drawable area.

  • sonium

Please post example code which replicates the problem and a full
traceback. From the snippet you posted, it looks like you may be
using the pylab/pyplot interface which is not consistent with
embedding mpl in qt or any other widget set. Rather, you need to be
using the mpl API.

JDH

···

On Sun, Jan 3, 2010 at 11:34 AM, Alexander Hupfer <sonium@...287...> wrote:

Hi, I have a scatter plot embedded in qt4 according to
http://matplotlib.sourceforge.net/examples/user_interfaces/embedding_in_qt4.html
what works fine
However if I try to add a colorbar to it by simply calling

p = scatter(....)
colorbar(p)

I get an error that says that something is outside the drawable area.

ok here comes some more code:

def plot_angles(results, axes):
lk.acquire()
x = list(results[0])
y = list(results[1])
lk.release()
p = axes.scatter(x,y, c = range(len(results[0])))
axes.set_xlabel(‘psi’)
axes.set_ylabel(‘delta’)
colorbar§

def update_figure(self):
plot_angles(results, self.axes)
self.draw()

_tkinter.TclError: bad screen distance “320.0”
Traceback (most recent call last):
File “/home/sonium/UbuntuOne/elipsometry/fitting.py”, line 156, in update_figure
plot_angles(results, self.axes)
File “/home/sonium/UbuntuOne/elipsometry/fitting.py”, line 173, in plot_angles
colorbar§
File “/usr/lib/pymodules/python2.6/matplotlib/pyplot.py”, line 1367, in colorbar
ax = gca()
File “/usr/lib/pymodules/python2.6/matplotlib/pyplot.py”, line 582, in gca
ax = gcf().gca(**kwargs)
File “/usr/lib/pymodules/python2.6/matplotlib/pyplot.py”, line 276, in gcf
return figure()
File “/usr/lib/pymodules/python2.6/matplotlib/pyplot.py”, line 254, in figure
**kwargs)
File “/usr/lib/pymodules/python2.6/matplotlib/backends/backend_tkagg.py”, line 91, in new_figure_manager
canvas = FigureCanvasTkAgg(figure, master=window)
File “/usr/lib/pymodules/python2.6/matplotlib/backends/backend_tkagg.py”, line 159, in init
self._tkcanvas.create_image(w/2, h/2, image=self._tkphoto)
File “/usr/lib/python2.6/lib-tk/Tkinter.py”, line 2159, in create_image
return self._create(‘image’, args, kw)
File “/usr/lib/python2.6/lib-tk/Tkinter.py”, line 2150, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: bad screen distance “320.0”

···

On Sun, Jan 3, 2010 at 1:07 PM, John Hunter <jdh2358@…287…> wrote:

On Sun, Jan 3, 2010 at 11:34 AM, Alexander Hupfer <sonium@…287…> wrote:

Hi, I have a scatter plot embedded in qt4 according to

http://matplotlib.sourceforge.net/examples/user_interfaces/embedding_in_qt4.html

what works fine

However if I try to add a colorbar to it by simply calling

p = scatter(…)

colorbar§

I get an error that says that something is outside the drawable area.

Please post example code which replicates the problem and a full

traceback. From the snippet you posted, it looks like you may be

using the pylab/pyplot interface which is not consistent with

embedding mpl in qt or any other widget set. Rather, you need to be

using the mpl API.

JDH

Hello,

You are using the TK backend.
Add this at the top of your script:

import matplotlib
matplotlib.use(‘QT4Agg’)

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar

Should work.
(Or at least will no more show errors related to TK backend…)

Laurent

Ok, that at least fixed the tkinter error, but I still don’t get a
colorbar attached to my plot. (which worked fine when I didn’t embedd
it in a Qt application)

···

On Sun, Jan 3, 2010 at 3:13 PM, Laurent Dufrechou <laurent.dufrechou@…287…> wrote:

Hello,

You are using the TK backend.
Add this at the top of your script:

import matplotlib

matplotlib.use(‘QT4Agg’)

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar

Should work.
(Or at least will no more show errors related to TK backend…)

Laurent

If you are importing from pylab or pyplot in your program, don't.
These modules are not compatible with embedding.

Darren

···

On Sun, Jan 3, 2010 at 5:26 PM, Alexander Hupfer <sonium@...287...> wrote:

Ok, that at least fixed the tkinter error, but I still don't get a colorbar
attached to my plot. (which worked fine when I didn't embedd it in a Qt
application)

Thanks I got it fixed.
This leads to the follow up question:
What is the right way to keep an application responsive while the graph is drawn?
Drawing a scatter plot with 300 points seems to take a while. I guess I need to launch the drawing in another thread but don’t know exactly how to do this and only find examples of doing calculations in the background and not actual widget interaction.

  • Alex
···

On Sun, Jan 3, 2010 at 3:37 PM, Darren Dale <dsdale24@…287…> wrote:

On Sun, Jan 3, 2010 at 5:26 PM, Alexander Hupfer <sonium@…287…> wrote:

Ok, that at least fixed the tkinter error, but I still don’t get a colorbar

attached to my plot. (which worked fine when I didn’t embedd it in a Qt

application)

If you are importing from pylab or pyplot in your program, don’t.

These modules are not compatible with embedding.

Darren

Alexander Hupfer wrote:

Thanks I got it fixed.
This leads to the follow up question:
What is the right way to keep an application responsive while the graph is drawn?
Drawing a scatter plot with 300 points seems to take a while. I guess I

That's strange--a scatter plot with 1000 points looks practically instantaneous to me. Are you using the Axes.scatter method?

Eric

···

need to launch the drawing in another thread but don't know exactly how to do this and only find examples of doing calculations in the background and not actual widget interaction.

- Alex

On Sun, Jan 3, 2010 at 3:37 PM, Darren Dale <dsdale24@…287… > <mailto:dsdale24@…287…>> wrote:

    On Sun, Jan 3, 2010 at 5:26 PM, Alexander Hupfer <sonium@…287… > <mailto:sonium@…287…>> wrote:
     > Ok, that at least fixed the tkinter error, but I still don't get
    a colorbar
     > attached to my plot. (which worked fine when I didn't embedd it
    in a Qt
     > application)

    If you are importing from pylab or pyplot in your program, don't.
    These modules are not compatible with embedding.

    Darren

------------------------------------------------------------------------

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev

------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

You posted some real code and a traceback, which helped move the ball
forward. What we really need to see to help you though is a complete,
free-standing example, that we can run on our machines, which exposes
the problem.

JDH

···

On Sun, Jan 3, 2010 at 7:02 PM, Alexander Hupfer <sonium@...287...> wrote:

Thanks I got it fixed.
This leads to the follow up question:
What is the right way to keep an application responsive while the graph is
drawn?
Drawing a scatter plot with 300 points seems to take a while. I guess I need
to launch the drawing in another thread but don't know exactly how to do
this and only find examples of doing calculations in the background and not
actual widget interaction.

Ok, here is the code as a whole. I think it’s still short enough to ilustrate the problem. Just start it with the datafile “elips” as an argument

http://dl.dropbox.com/u/226980/elipsometry.tar.gz

The timer shows how long each render cycle takes. The time seems to grow with number of cycles rendered even when no more points are added (the points are calculated with a continous rate in a background thread and are about 300 total).

···

On Sun, Jan 3, 2010 at 8:16 PM, John Hunter <jdh2358@…1896…> wrote:

On Sun, Jan 3, 2010 at 7:02 PM, Alexander Hupfer <sonium@…287…> wrote:

Thanks I got it fixed.

This leads to the follow up question:

What is the right way to keep an application responsive while the graph is

drawn?

Drawing a scatter plot with 300 points seems to take a while. I guess I need

to launch the drawing in another thread but don’t know exactly how to do

this and only find examples of doing calculations in the background and not

actual widget interaction.

You posted some real code and a traceback, which helped move the ball

forward. What we really need to see to help you though is a complete,

free-standing example, that we can run on our machines, which exposes

the problem.

JDH

I isolated the problem a bit more. For some reason drawing gets slower and slower with each plot drawn.

from os import sys
from time import time
from PyQt4 import QtGui, QtCore

import matplotlib

matplotlib.use(‘QT4Agg’)

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

class MyMplCanvas(FigureCanvas):
“”“Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.).”""
def init(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
# We want the axes cleared every time plot() is called
self.axes.hold(False)

    self.compute_initial_figure()
···
    #
    FigureCanvas.__init__(self, fig)
    self.setParent(parent)

    FigureCanvas.setSizePolicy(self,
                               QtGui.QSizePolicy.Expanding,
                               QtGui.QSizePolicy.Expanding)
    FigureCanvas.updateGeometry(self)

def compute_initial_figure(self):
    pass

class MyDynamicMplCanvas(MyMplCanvas):
“”“A canvas that updates itself every second with a new plot.”""
def init(self, *args, **kwargs):
MyMplCanvas.init(self, *args, **kwargs)
timer = QtCore.QTimer(self)
QtCore.QObject.connect(timer, QtCore.SIGNAL(“timeout()”), self.update_figure)
timer.start(0)
self.firstrun = True
self.colorbar = None
self.time = time()
self.p = None
def compute_initial_figure(self):
pass

def update_figure(self):
    self.p = self.axes.scatter([1,2,3],[4,5,6], c = range(3), animated=True)
    self.axes.set_xlabel('psi')
    self.axes.set_ylabel('delta')
    if self.firstrun == True:
        self.colorbar = self.axes.figure.colorbar(self.p)
        self.firstrun = False
    self.colorbar.set_clim(vmin=0,vmax=2)
    self.colorbar.draw_all()
    self.colorbar.set_label('time [abtr. ]')
    self.draw()
    newtime = time()
    print newtime - self.time
    self.time = newtime

class ApplicationWindow(QtGui.QMainWindow):
def init(self):
QtGui.QMainWindow.init(self)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

    self.main_widget = QtGui.QWidget(self)

    l = QtGui.QVBoxLayout(self.main_widget)

    dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)

    l.addWidget(dc)

    self.main_widget.setFocus()
    self.setCentralWidget(self.main_widget)

qApp = QtGui.QApplication(sys.argv)

aw = ApplicationWindow()
aw.setWindowTitle("%s" % “Slow!”)
aw.setGeometry(100,100,800,600)
aw.show()
sys.exit(qApp.exec_())

On Mon, Jan 4, 2010 at 3:36 PM, Alexander Hupfer <sonium@…287…> wrote:

Ok, here is the code as a whole. I think it’s still short enough to ilustrate the problem. Just start it with the datafile “elips” as an argument

http://dl.dropbox.com/u/226980/elipsometry.tar.gz

The timer shows how long each render cycle takes. The time seems to grow with number of cycles rendered even when no more points are added (the points are calculated with a continous rate in a background thread and are about 300 total).

On Sun, Jan 3, 2010 at 8:16 PM, John Hunter <jdh2358@…287…> wrote:

On Sun, Jan 3, 2010 at 7:02 PM, Alexander Hupfer <sonium@…287…> wrote:

Thanks I got it fixed.

This leads to the follow up question:

What is the right way to keep an application responsive while the graph is

drawn?

Drawing a scatter plot with 300 points seems to take a while. I guess I need

to launch the drawing in another thread but don’t know exactly how to do

this and only find examples of doing calculations in the background and not

actual widget interaction.

You posted some real code and a traceback, which helped move the ball

forward. What we really need to see to help you though is a complete,

free-standing example, that we can run on our machines, which exposes

the problem.

JDH

Hi alexander,

I tryed yesterday to play a little with your script.

I suspect that in fact each time you draw a figure, it is added
to a pool of figure to be rendered.

Thus it goes slower and slower.

What I do in my scritpt is either update the datas or if the
drawing is a completely new one (like a polar ionstaed of log previously) I delete
the figure.

To update data use:

1/self._plot, = axe.plot(x, y, ‘b’, animated=self._animated)

Later:

Loop:

2/self._plot.set_ydata(self._value)

If you need to delete your figure (that is not your case, but
who knows for the future):

axe = fig.add_axes(self.getPosition())

self._fig.delaxes(self._axe)

To go even faster(x10) you have the blitting method, but
set_ydata should be sufficent.

Laurent

···

De : Alexander Hupfer
[mailto:sonium@…287…]
Envoyé : jeudi 7 janvier 2010 03:36
C****c :
matplotlib-users@…1220…sts.sourceforge.net
Objet : Re: [Matplotlib-users] Colorbar embedding in qt4

I isolated the problem a bit
more. For some reason drawing gets slower and slower with each plot drawn.

from os import sys
from time import time
from PyQt4 import QtGui, QtCore

import matplotlib

matplotlib.use(‘QT4Agg’)

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as
FigureCanvas
from matplotlib.figure import Figure

class MyMplCanvas(FigureCanvas):
“”“Ultimately, this is a QWidget (as well as
a FigureCanvasAgg, etc.).”""
def init(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width,
height), dpi=dpi)
self.axes = fig.add_subplot(111)
# We want the axes cleared every
time plot() is called
self.axes.hold(False)

    self.compute_initial_figure()

    #
    FigureCanvas.__init__(self, fig)
    self.setParent(parent)

    FigureCanvas.setSizePolicy(self,

QtGui.QSizePolicy.Expanding,

QtGui.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)

def compute_initial_figure(self):
    pass

class MyDynamicMplCanvas(MyMplCanvas):
“”“A canvas that updates itself every second
with a new plot.”""
def init(self, *args, **kwargs):
MyMplCanvas.init(self, *args,
**kwargs)
timer = QtCore.QTimer(self)
QtCore.QObject.connect(timer,
QtCore.SIGNAL(“timeout()”), self.update_figure)
timer.start(0)
self.firstrun = True
self.colorbar = None
self.time = time()
self.p = None
def compute_initial_figure(self):
pass

def update_figure(self):
    self.p =

self.axes.scatter([1,2,3],[4,5,6], c = range(3), animated=True)
self.axes.set_xlabel(‘psi’)
self.axes.set_ylabel(‘delta’)
if self.firstrun == True:

self.colorbar = self.axes.figure.colorbar(self.p)

self.firstrun = False

self.colorbar.set_clim(vmin=0,vmax=2)
self.colorbar.draw_all()
self.colorbar.set_label(‘time [abtr.
]’)
self.draw()
newtime = time()
print newtime - self.time
self.time = newtime

class ApplicationWindow(QtGui.QMainWindow):
def init(self):
QtGui.QMainWindow.init(self)

self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

    self.main_widget =

QtGui.QWidget(self)

    l = QtGui.QVBoxLayout(self.main_widget)

    dc =

MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)

    l.addWidget(dc)

    self.main_widget.setFocus()

self.setCentralWidget(self.main_widget)

qApp = QtGui.QApplication(sys.argv)

aw = ApplicationWindow()
aw.setWindowTitle("%s" % “Slow!”)
aw.setGeometry(100,100,800,600)
aw.show()
sys.exit(qApp.exec_())

On Mon, Jan 4, 2010 at 3:36 PM, Alexander Hupfer <sonium@…287…> wrote:

Ok, here is the code as a whole. I think it’s still short
enough to ilustrate the problem. Just start it with the datafile
“elips” as an argument

http://dl.dropbox.com/u/226980/elipsometry.tar.gz

The timer shows how long each render cycle takes. The time seems to grow with
number of cycles rendered even when no more points are added (the points are
calculated with a continous rate in a background thread and are about 300
total).

On Sun, Jan 3, 2010 at 8:16 PM, John Hunter <jdh2358@…287…> wrote:

On Sun, Jan 3, 2010 at 7:02 PM, Alexander Hupfer <sonium@…287…> wrote:

Thanks I got it fixed.
This leads to the follow up question:
What is the right way to keep an application responsive while the graph is
drawn?
Drawing a scatter plot with 300 points seems to take a while. I guess I
need
to launch the drawing in another thread but don’t know exactly how to do
this and only find examples of doing calculations in the background and
not
actual widget interaction.

You posted some real code and a traceback, which helped move
the ball
forward. What we really need to see to help you though is a complete,
free-standing example, that we can run on our machines, which exposes
the problem.

JDH

Hi, thanks for having a look at this.

Problem is that a scatter plot doesn’t seem to have the option to actually update the data, or at least I couldn’t find it.

Is there maybe a way?

···

On Thu, Jan 7, 2010 at 2:58 AM, Laurent Dufrechou <laurent.dufrechou@…287…> wrote:

Hi alexander,

I tryed yesterday to play a little with your script.

I suspect that in fact each time you draw a figure, it is added
to a pool of figure to be rendered.

Thus it goes slower and slower.

What I do in my scritpt is either update the datas or if the
drawing is a completely new one (like a polar ionstaed of log previously) I delete
the figure.

To update data use:

1/self._plot, = axe.plot(x, y, ‘b’, animated=self._animated)

Later:

Loop:

2/self._plot.set_ydata(self._value)

If you need to delete your figure (that is not your case, but
who knows for the future):

axe = fig.add_axes(self.getPosition())

self._fig.delaxes(self._axe)

To go even faster(x10) you have the blitting method, but
set_ydata should be sufficent.

Laurent

De : Alexander Hupfer
[mailto:sonium@…1972…]
Envoyé : jeudi 7 janvier 2010 03:36
C****c :
matplotlib-users@…1220…sts.sourceforge.net
Objet : Re: [Matplotlib-users] Colorbar embedding in qt4

I isolated the problem a bit
more. For some reason drawing gets slower and slower with each plot drawn.

from os import sys
from time import time
from PyQt4 import QtGui, QtCore

import matplotlib

matplotlib.use(‘QT4Agg’)

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as
FigureCanvas
from matplotlib.figure import Figure

class MyMplCanvas(FigureCanvas):
“”“Ultimately, this is a QWidget (as well as
a FigureCanvasAgg, etc.).”""
def init(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width,
height), dpi=dpi)
self.axes = fig.add_subplot(111)
# We want the axes cleared every
time plot() is called
self.axes.hold(False)

    self.compute_initial_figure()

    #
    FigureCanvas.__init__(self, fig)
    self.setParent(parent)

    FigureCanvas.setSizePolicy(self,

QtGui.QSizePolicy.Expanding,

QtGui.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)

def compute_initial_figure(self):
    pass

class MyDynamicMplCanvas(MyMplCanvas):
“”“A canvas that updates itself every second
with a new plot.”""
def init(self, *args, **kwargs):
MyMplCanvas.init(self, *args,
**kwargs)
timer = QtCore.QTimer(self)
QtCore.QObject.connect(timer,
QtCore.SIGNAL(“timeout()”), self.update_figure)
timer.start(0)
self.firstrun = True
self.colorbar = None
self.time = time()
self.p = None
def compute_initial_figure(self):
pass

def update_figure(self):
    self.p =

self.axes.scatter([1,2,3],[4,5,6], c = range(3), animated=True)
self.axes.set_xlabel(‘psi’)
self.axes.set_ylabel(‘delta’)
if self.firstrun == True:

self.colorbar = self.axes.figure.colorbar(self.p)

self.firstrun = False

self.colorbar.set_clim(vmin=0,vmax=2)
self.colorbar.draw_all()
self.colorbar.set_label(‘time [abtr.
]’)
self.draw()
newtime = time()
print newtime - self.time
self.time = newtime

class ApplicationWindow(QtGui.QMainWindow):
def init(self):
QtGui.QMainWindow.init(self)

self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

    self.main_widget =

QtGui.QWidget(self)

    l = QtGui.QVBoxLayout(self.main_widget)

    dc =

MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)

    l.addWidget(dc)

    self.main_widget.setFocus()

self.setCentralWidget(self.main_widget)

qApp = QtGui.QApplication(sys.argv)

aw = ApplicationWindow()
aw.setWindowTitle("%s" % “Slow!”)
aw.setGeometry(100,100,800,600)
aw.show()
sys.exit(qApp.exec_())

On Mon, Jan 4, 2010 at 3:36 PM, Alexander Hupfer <sonium@…287…> wrote:

Ok, here is the code as a whole. I think it’s still short
enough to ilustrate the problem. Just start it with the datafile
“elips” as an argument

http://dl.dropbox.com/u/226980/elipsometry.tar.gz

The timer shows how long each render cycle takes. The time seems to grow with
number of cycles rendered even when no more points are added (the points are
calculated with a continous rate in a background thread and are about 300
total).

On Sun, Jan 3, 2010 at 8:16 PM, John Hunter <jdh2358@…287…> > wrote:

On Sun, Jan 3, 2010 at 7:02 PM, > Alexander Hupfer <sonium@…287…> > wrote:

Thanks I got it fixed.
This leads to the follow up question:
What is the right way to keep an application responsive while the graph is
drawn?
Drawing a scatter plot with 300 points seems to take a while. I guess I
need
to launch the drawing in another thread but don’t know exactly how to do
this and only find examples of doing calculations in the background and
not
actual widget interaction.

You posted some real code and a traceback, which helped move
the ball
forward. What we really need to see to help you though is a complete,
free-standing example, that we can run on our machines, which exposes
the problem.

JDH