Two panels (wxPython) containing separate figures

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py", line 1374, in _sci
    "Argument must be an image, collection, or ContourSet in this Axes")
ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh

panel_test.py (1.73 KB)

To get rid of the networkx dependency, I just replaced my_plot() with this:

def my_plot(figure):

figure.clear()

axes = figure.add_subplot(1,1,1)

axes.plot([0,1,2],[2,3,4])

and also added “self.panel2.update_display()” in the constructor for MyFrame, and everything worked fine. Could it be networkx caching a reference to a figure or axes that is really the problem? Can you post the full stack trace instead of just the last line?

···

On Wed, Jul 11, 2012 at 12:45 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

"Argument must be an image, collection, or ContourSet in this Axes")

ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh


Live Security Virtual Conference

Exclusive live event will cover all the ways today’s security and

threat landscape has changed and how IT managers can respond. Discussions

will include endpoint security, mobile security and the latest in malware

threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Daniel Hyams
dhyams@…1972…

Josh,

Can you please post the entire traceback? My suspicion for what is happening is that both figures are sharing the same canvas, but I am not exactly sure. Anyway, when you perform a plot on one panel, you are calling “clear()” for that figure, which may be having side-effects for the other figure since it is attached to the same Wx object.

Actually, looking over your code again, I see a few things that may or may not be part of the problem, but should be addressed, nevertheless. First, you are calling FigureCanvas and assigning it to self.canvas. This canvas is different from the canvas that the figure will actually use, so I am not sure if this is being done correctly. Second, your call to “plt.close()” assumes that the figure you want to close is the currently active figure. What you want to call is “plt.close(self.figure)” in order to make sure it closes the figure you intend to close.

Ben Root

···

On Wed, Jul 11, 2012 at 12:45 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

"Argument must be an image, collection, or ContourSet in this Axes")

ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh

Just from morbid curiosity, I installed networkx to see if I could see what is going on. And the answer to your original question is that no, matplotlib doesn’t have problems with multiple wx panels; I do this all the time.

Basically what is going on is that pylab is being used inside of networkx to issue the plotting commands. That’s a bad idea in general, because of just this type of situation. Without getting in there and trying to fix networkx, I can at least make your script work by inserting this line:

def my_plot(figure):

figure.clear()

plt.figure(figure.number) <-------------------------------

G = nx.star_graph(15)

axes = figure.add_subplot(1,1,1)

nx.draw_networkx(G, ax=axes)

to make sure that before nx.draw_networkx is invoked, the correct figure is current. That’s a kludge, but it does work. The proper solution is to modify networkx to use the api’s properly. In particular, the glaring one is right at the top of

site-packages/networkx/drawing/nx_pylab.py, line 119; that

cf = pylab.gcf()

should at least be

if ax is None:

cf = pylab.gcf()

else:

cf = ax.get_figure()

[I think]

The above should be reported to the networkx authors.

···

On Wed, Jul 11, 2012 at 1:02 PM, Daniel Hyams <dhyams@…287…> wrote:

To get rid of the networkx dependency, I just replaced my_plot() with this:

def my_plot(figure):

figure.clear()

axes = figure.add_subplot(1,1,1)

axes.plot([0,1,2],[2,3,4])

and also added “self.panel2.update_display()” in the constructor for MyFrame, and everything worked fine. Could it be networkx caching a reference to a figure or axes that is really the problem? Can you post the full stack trace instead of just the last line?

On Wed, Jul 11, 2012 at 12:45 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

"Argument must be an image, collection, or ContourSet in this Axes")

ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh


Live Security Virtual Conference

Exclusive live event will cover all the ways today’s security and

threat landscape has changed and how IT managers can respond. Discussions

will include endpoint security, mobile security and the latest in malware

threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Daniel Hyams
dhyams@…287…


Daniel Hyams
dhyams@…287…

Here is the full traceback from the sample program:

Traceback (most recent call last):

File “panel_test.py”, line 54, in

frame = MyFrame(None)

File “panel_test.py”, line 42, in init

self.panel1.update_display()

File “panel_test.py”, line 19, in update_display

my_plot(self.figure)

File “panel_test.py”, line 10, in my_plot

nx.draw_networkx(G, ax=axes)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/networkx/drawing/nx_pylab.py”, line 269, in draw_networkx

node_collection=draw_networkx_nodes(G, pos, **kwds)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/networkx/drawing/nx_pylab.py”, line 392, in draw_networkx_nodes

pylab.sci(node_collection)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/pyplot.py”, line 226, in sci

gca()._sci(im)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

“Argument must be an image, collection, or ContourSet in this Axes”)

ValueError: Argument must be an image, collection, or ContourSet in this Axes

Thanks guys!

Josh

···

On Jul 11, 2012, at 1:18 PM, Benjamin Root wrote:

On Wed, Jul 11, 2012 at 12:45 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

"Argument must be an image, collection, or ContourSet in this Axes")

ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh

Josh,

Can you please post the entire traceback? My suspicion for what is happening is that both figures are sharing the same canvas, but I am not exactly sure. Anyway, when you perform a plot on one panel, you are calling “clear()” for that figure, which may be having side-effects for the other figure since it is attached to the same Wx object.

Actually, looking over your code again, I see a few things that may or may not be part of the problem, but should be addressed, nevertheless. First, you are calling FigureCanvas and assigning it to self.canvas. This canvas is different from the canvas that the figure will actually use, so I am not sure if this is being done correctly. Second, your call to “plt.close()” assumes that the figure you want to close is the currently active figure. What you want to call is “plt.close(self.figure)” in order to make sure it closes the figure you intend to close.

Ben Root

Josh:

I’m assuming that you saw the workaround two messages up?

···

On Wed, Jul 11, 2012 at 1:41 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Here is the full traceback from the sample program:

Traceback (most recent call last):

File “panel_test.py”, line 54, in

frame = MyFrame(None)

File “panel_test.py”, line 42, in init

self.panel1.update_display()

File “panel_test.py”, line 19, in update_display

my_plot(self.figure)

File “panel_test.py”, line 10, in my_plot

nx.draw_networkx(G, ax=axes)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/networkx/drawing/nx_pylab.py”, line 269, in draw_networkx

node_collection=draw_networkx_nodes(G, pos, **kwds)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/networkx/drawing/nx_pylab.py”, line 392, in draw_networkx_nodes

pylab.sci(node_collection)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/pyplot.py”, line 226, in sci

gca()._sci(im)

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

“Argument must be an image, collection, or ContourSet in this Axes”)

ValueError: Argument must be an image, collection, or ContourSet in this Axes

Thanks guys!

Josh

On Jul 11, 2012, at 1:18 PM, Benjamin Root wrote:

On Wed, Jul 11, 2012 at 12:45 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

"Argument must be an image, collection, or ContourSet in this Axes")

ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh

Josh,

Can you please post the entire traceback? My suspicion for what is happening is that both figures are sharing the same canvas, but I am not exactly sure. Anyway, when you perform a plot on one panel, you are calling “clear()” for that figure, which may be having side-effects for the other figure since it is attached to the same Wx object.

Actually, looking over your code again, I see a few things that may or may not be part of the problem, but should be addressed, nevertheless. First, you are calling FigureCanvas and assigning it to self.canvas. This canvas is different from the canvas that the figure will actually use, so I am not sure if this is being done correctly. Second, your call to “plt.close()” assumes that the figure you want to close is the currently active figure. What you want to call is “plt.close(self.figure)” in order to make sure it closes the figure you intend to close.

Ben Root


Live Security Virtual Conference

Exclusive live event will cover all the ways today’s security and

threat landscape has changed and how IT managers can respond. Discussions

will include endpoint security, mobile security and the latest in malware

threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Daniel Hyams
dhyams@…1972…

That did the trick. I tried going through the source code but it just got too messy. How do I let the networkx developers know about this?

···

On Jul 11, 2012, at 1:18 PM, Benjamin Root wrote:

On Wed, Jul 11, 2012 at 12:45 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

"Argument must be an image, collection, or ContourSet in this Axes")

ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh

Josh,

Can you please post the entire traceback? My suspicion for what is happening is that both figures are sharing the same canvas, but I am not exactly sure. Anyway, when you perform a plot on one panel, you are calling “clear()” for that figure, which may be having side-effects for the other figure since it is attached to the same Wx object.

Actually, looking over your code again, I see a few things that may or may not be part of the problem, but should be addressed, nevertheless. First, you are calling FigureCanvas and assigning it to self.canvas. This canvas is different from the canvas that the figure will actually use, so I am not sure if this is being done correctly. Second, your call to “plt.close()” assumes that the figure you want to close is the currently active figure. What you want to call is “plt.close(self.figure)” in order to make sure it closes the figure you intend to close.

Ben Root

You can either send them the link to this discussion, or just the little snippet concerning gcf() above; just taking care of that would be an improvement.

···

On Thu, Jul 12, 2012 at 10:17 AM, Joshua Koehler <jjkoehler9@…287…> wrote:

That did the trick. I tried going through the source code but it just got too messy. How do I let the networkx developers know about this?
On Jul 11, 2012, at 1:18 PM, Benjamin Root wrote:

On Wed, Jul 11, 2012 at 12:45 PM, Joshua Koehler <jjkoehler9@…287…> wrote:

Hi all,

I am currently trying to have two panels each with their own figure instance so they can have separate plots.

I can successfully update a plot if there is only one panel. As soon as I add a second panel, I get the following error when I try to update (replot) a plot (Showing last message only):

File “/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py”, line 1374, in _sci

"Argument must be an image, collection, or ContourSet in this Axes")

ValueError: Argument must be an image, collection, or ContourSet in this Axes

I looked online first and one site suggested it was because I was using matplotlib.Figure instead of pylab.Figure. I switched and the problem still occurs. I was curious to see if this problem had to do with how I set up my program, not with matplotlib, so I wrote a little test program. The exact same problem occurs. I have attached the test program. To see that it does work with just one panel comment out lines 39, 41, and 49. When put back in, I get the above error message.

Any suggestions as to how to fix this?

Thanks!

Josh

Josh,

Can you please post the entire traceback? My suspicion for what is happening is that both figures are sharing the same canvas, but I am not exactly sure. Anyway, when you perform a plot on one panel, you are calling “clear()” for that figure, which may be having side-effects for the other figure since it is attached to the same Wx object.

Actually, looking over your code again, I see a few things that may or may not be part of the problem, but should be addressed, nevertheless. First, you are calling FigureCanvas and assigning it to self.canvas. This canvas is different from the canvas that the figure will actually use, so I am not sure if this is being done correctly. Second, your call to “plt.close()” assumes that the figure you want to close is the currently active figure. What you want to call is “plt.close(self.figure)” in order to make sure it closes the figure you intend to close.

Ben Root


Live Security Virtual Conference

Exclusive live event will cover all the ways today’s security and

threat landscape has changed and how IT managers can respond. Discussions

will include endpoint security, mobile security and the latest in malware

threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Daniel Hyams
dhyams@…1972…