SourceForge logo
SourceForge logo
Menu

[matplotlib-devel] Re: wx

From: Jeremy O'D. <je...@o-...> - 2004年02月14日 11:14:53
Attachments: backend_wx.py
On Saturday 14 February 2004 8:03 am, you wrote:
> Thanks for the pointers.
>
> On Friday 13 February 2004 9:20 pm, you wrote:
> > I made some progress!
>
> [snup]
>
> > The bug was a line I introduced when I added some more print
> > debugs
>
> I had fixed this one...
>
> > The front end change that is causing your problems is that I now pass
> > a gcedge and a gcface. I used to pass a gcface and a face color.
> > Maybe I'll revert to that.
> >
> > When I instantiate a gcedge and a gcface on the front end, you make 2
> > calls to new_gc
> >
> > def new_gc(self):
> > """
> > Return an instance of a GraphicsContextWx, and sets the current
> > gc copy """
> > DEBUG_MSG('new_gc()', 2, self)
> > self.gc = GraphicsContextWx(self.bitmap, self)
> > assert self.gc.Ok(), "wxMemoryDC not OK to use"
> > return self.gc
> >
> > I think initing 2 GCs with the same bitmap is causing the problem. If
> > you see an easy backend solution, that would be ideal. If not, I
> > could re-refactor the frontend to be like it was: pass a gcedge and a
> > facecolor.
>
> This is, indeed, illegal in wx. It sometimes works under Windows, but
> consistently fails (dramatically) under Linux (at least for wxGtk).
To be more exact about what happens, here is the synopsis:
In patches.py, Patch._draw() instantiates two gc instances
 def _draw(self, renderer, *args, **kwargs):
#here=============>
 gc = renderer.new_gc() 
 gc.set_foreground(self._edgecolor)
 gc.set_linewidth(self._linewidth)
 gc.set_alpha(self._alpha)
 if self._clipOn:
 gc.set_clip_rectangle(self.bbox.get_bounds())
 if not self.fill: gcFace = None
 else:
#and here===========>
 gcFace = renderer.new_gc() 
 gcFace.set_foreground(self._facecolor)
 gcFace.set_alpha(self._alpha)
 self._derived_draw(renderer, gc, gcFace)
Each call to backend_wx.py RendererWx.new_gc() does the following:
 self.gc = GraphicsContextWx(self.bitmap, self)
 assert self.gc.Ok(), "wxMemoryDC not OK to use"
 return self.gc
But instantiating a GraphicsContextWx does:
 def __init__(self, bitmap, renderer):
 GraphicsContextBase.__init__(self)
 wxMemoryDC.__init__(self)
 DEBUG_MSG("__init__()", 1, self)
 # Make sure (belt and braces!) that existing wxDC is not selected to
 # to a bitmap.
 if GraphicsContextWx._lastWxDC != None:
#the gcEdge gets selected into a NULL bitmap here
 GraphicsContextWx._lastWxDC.SelectObject(wxNullBitmap)
 self.SelectObject(bitmap)
 self.SetPen(wxPen('BLACK', 1, wxSOLID))
 self._style = wxSOLID
 self.renderer = renderer 
 GraphicsContextWx._lastWxDC = self
You will note that in order to enforce the wx rule that no more than one 
wxMemoryDC can be selected into a bitmap, I ensure that the last wxMemoryDC 
instance activated is selected to a wxNullBitmap.
In the case of the above code, this means that the gc representing the 
rectangle has already been selected to a NULL bitmap. When you try to draw to 
this, an exception is generated within the C++ code which is not propagated 
back up to the Python layer. Unfortunately, the assert() calls don't help 
much here as each gc instance is OK when it is constructed.
I'm afraid I'd missed the significance of the change from a facecolor to a 
gcFace for fill colours.
> I'll see if I can come up with any ideas, but passing a gcedge and
> facecolor is likely to be simpler to get to work reliably.
I have thought about this, and to only other option I can think of is for me 
to select between 'currently active' gc instances as required. Obviously, 
this would probably slow backend_wx down, but I'm not yet sure what the 
performance hit will be. Let me try it...
[an hour or so later...]
Attached is a backend_wx which seems to work with most of the examples I've 
tried (Linux only - expect Windows to work as it's generally better behaved 
than wxGtk, but would be nice if someone would try it.
Some issues (for now):
- Clipping seems to be broken (c.f. arctest.py)
- Object picker demo doesn't work (haven't implemented this functionality)
- Some types of dotted lines are not working properly (c.f. subplot_demo.py)
- embedding_in_wx doesn't work - due to some of the recent API changes. I'll 
fix this one pretty soon - it shouldn't be much work.
- It's about 20% slower than the previous implementation in which only one GC 
was active at a time.
Not sure if the dotted lines and clipping are down to information being lost 
when I switch between gcs - I'll have to look into this, but the attached 
will be a good start for getting things to work on wx again.
John, I'll leave it as your call whether you want to switch the API back to 
using a facecolor instead of a gcFace. It would be better from the wx 
perspective, but there may be good reasons for doing otherwise on other 
backends. 
There are a couple of optimisations I can probably make to speed things a 
little if we stick with the current API -it should be possible to do 
something slightly more intelligent than simply selecting a bitmap at the 
start of each call, and deselecting it afterwards - although, as noted above, 
wxMemoryDC seems to be extremely fragile under wxGtk - not sure why.
I have checked the attached into CVS for now, but we may have the usual 
'mirror update' issue.
Regards
Jeremy

View entire thread

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /