esheldon / pymangle

Simple code to read mangle masks, calculate ids and weights, and generate random points
14 stars 15 forks source link

Error when reading file after importing `pyplot` in IPython/Jupyter #18

Open parnalte opened 5 years ago

parnalte commented 5 years ago

Hi,

First of all, thanks a lot for the code! :)

I'm getting a strange error when trying to read a polygon file from the IPython console. I can read a file without problems initially but, if I first import matplotlib.pyplot and try to read a polygon file afterwards, I get an OSError. Here's a transcript:

(base) pablo@mimas:$ ipython
Python 3.7.3 (default, Mar 27 2019, 22:11:17) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.8.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pymangle                                                                                               

In [2]: m = pymangle.Mangle("basic_rect_mask.ply")                                                                    

In [3]: m                                                                                                             
Out[3]: 
Mangle
    file:       basic_rect_mask.ply
    area:       2.26946 sqdeg
    npoly:      1
    pixeltype:  'u'
    pixelres:   -1
    real:       10
    npix:       0
    snapped:    0
    balkanized: 0
    weightfile: 
    verbose:    0

In [4]: m.area                                                                                                        
Out[4]: 2.2694632669506295698

In [5]: import matplotlib.pyplot as plt                                                                               

In [6]: m2 = pymangle.Mangle("basic_rect_mask.ply")                                                                   
Failed to read cap
failed to read polygon 0
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-6-5ca19ad5eaa4> in <module>
----> 1 m2 = pymangle.Mangle("basic_rect_mask.ply")

~/anaconda3/lib/python3.7/site-packages/pymangle/mangle.py in __init__(self, filename, verbose)
     56         else:
     57             verb=0
---> 58         super(Mangle,self).__init__(filename,verb)
     59 
     60     def read_weights(self, weightfile):

OSError: Error reading mangle mask basic_rect_mask.ply

In [7]: !cat basic_rect_mask.ply                                                                                      
1 polygons
polygon 0 ( 4 caps, 1 weight, 0 pixel, 0.000691318044679215 str):
 0.5372996083468238328 -0.8433914458128857007 0.0000000000000000005 1
 0.6552660971010802629 0.4378348082356948762 0.6155704855555779053 1
 -0.5735764363510460959 0.8191520442889917898 0.0000000000000000005 1
 -0.6684388292532475694 -0.4466365464628057830 -0.5947313064824531940 1

Some things I've tried:

Relevant versions (from Anaconda):

Of course, it is easy to work around this issue (just read your files before importing pyplot) but I'm curious whether there is a fix for it.

Cheers, Pablo.

PS. Sorry I hit 'Enter' too early when starting to write!

esheldon commented 5 years ago

Can you please try with the latest master? We just fixed a bug which might have been causing your problem

parnalte commented 4 years ago

Hi, Thanks for the answer. I tried with the new version (current master) and I get the same errors, nothing has (apparently) changed.

BTW, from an additional test, I found that I do not get the error in Jupyter Notebook if I use the %matplotlib inline magic command (I do get the error when using just %matplotlib). I suspect therefore that the error may come from some problem due to the backend that matplotlib uses for interactive plots (in my case, Qt5Agg).

Thanks, Pablo.

esheldon commented 4 years ago

I've tried it with some of my own masks and I don't see the error.

Can you please post the mask you are using?

esheldon commented 4 years ago

sorry, I see you did post it in your code snippet

I also do not see an error using that mask

esheldon commented 4 years ago

Are you using linux or mac?

parnalte commented 4 years ago

Hi, Thanks for your answers!

I am quite certain this error does not depend on the mask used, as I have tried several ones with the same result. I am using Linux (Linux Mint 19.2, which is based on Ubuntu 18.04) and, as I said, this is probably related to the Qt5Agg backend (I assume a different backend may be used by default in a Mac).

I did some tests switching the backend used by matplotlib. The issue disappears if I use the TkAgg backend instead:

(base) pablo@mimas$ ipython
Python 3.7.3 (default, Mar 27 2019, 22:11:17) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.8.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pymangle                                                                                               

In [2]: pymangle.__version__                                                                                          
Out[2]: '0.9.2'

In [3]: m = pymangle.Mangle("basic_rect_mask.ply", verbose=True)                                                      
Expect 1 polygons
reading 1 polygons

In [4]: m                                                                                                             
Out[4]: 
Mangle
    file:       basic_rect_mask.ply
    area:       2.26946 sqdeg
    npoly:      1
    pixeltype:  'u'
    pixelres:   -1
    real:       10
    npix:       0
    snapped:    0
    balkanized: 0
    weightfile: 
    verbose:    1

In [5]: %matplotlib tk                                                                                                

In [6]: import matplotlib.pyplot as plt                                                                               

In [7]: plt.get_backend()                                                                                             
Out[7]: 'TkAgg'

In [8]: m2 = pymangle.Mangle("basic_rect_mask.ply", verbose=True)                                                     
Expect 1 polygons
reading 1 polygons

In [9]: m2                                                                                                            
Out[9]: 
Mangle
    file:       basic_rect_mask.ply
    area:       2.26946 sqdeg
    npoly:      1
    pixeltype:  'u'
    pixelres:   -1
    real:       10
    npix:       0
    snapped:    0
    balkanized: 0
    weightfile: 
    verbose:    1

With this workaround, I can load masks with pymangle normally, and I can also use the pyplot interactive plotting as usual, although using the slightly "old fashioned" Tk backend.

The issue also disappears if I use any of the non-interactive backends (e.g. using import matplotlib as mpl; mpl.use('agg') before importing pyplot). Although in that case, obviously, I can not do interactive plots afterwards.

So my best guess is that this should have to do somehow with the Qt5Agg backend and/or the PyQt5 module, but I do not understand how this could affect pymangle.

In any case, this may be something specific to my configuration and I am happy with this solution, so I wouldn't spend too much time on this issue (unless you think it may be useful for other users or it may affect pymangle in some other way, of course). But let me know if you want me to do any additional test.

Thanks, Pablo.

esheldon commented 4 years ago

I should have said before, my tests were all done using the Qt5Agg backend, as well as all your versions and I didn't see any problems. Have you tried on a different system?

parnalte commented 4 years ago

I tried a different system, but with the same Linux Mint version (so probably not very useful), with the same results. Did you do your tests also using Linux?

esheldon commented 4 years ago

Yes, I'm using ubuntu 18.04.3 LTS