Difference between revisions of "Matplotlib dateutil bug"

From relax wiki
Jump to navigation Jump to search
(Forced creation of a TOC - this will improve the formatting on the main page 'Did you know...' section.)
 
(12 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
__TOC__
 +
 
== Background ==
 
== Background ==
 
When you create a range in relax, it is created as an xrange object.<br>
 
When you create a range in relax, it is created as an xrange object.<br>
 +
This is due to memory issues, which you can read about [http://thread.gmane.org/gmane.science.nmr.relax.devel/4862/focus=4865 here.]
  
 
You cannot by default slice through xrange objects.
 
You cannot by default slice through xrange objects.
  
The '''dateutil.rrule''' package used in matplotlib/pylab creates some list, which it expects it can slice through.<br>
+
The '''dateutil.rrule''' package (version 1.5) used in matplotlib/pylab creates some list, which it expects it can slice through.<br>
 +
'''dateutil.rrule''' package (version 2.2) does not have this problem.
 +
 
 
But relax will create these as '''xrange''' which is not-sliceable.
 
But relax will create these as '''xrange''' which is not-sliceable.
  
Line 17: Line 22:
 
>>> print x[:3]
 
>>> print x[:3]
 
[0, 1, 2]
 
[0, 1, 2]
 +
 +
# Lets create an xrange object.
 
>>> y=xrange(10)
 
>>> y=xrange(10)
 
>>> type(y)
 
>>> type(y)
Line 25: Line 32:
 
TypeError: sequence index must be integer, not 'slice'
 
TypeError: sequence index must be integer, not 'slice'
 
</source>
 
</source>
 
+
Now let's try in relax.
 
<source lang="python">
 
<source lang="python">
 
USER@MACHINE: $ relax
 
USER@MACHINE: $ relax
Line 36: Line 43:
 
   File "<console>", line 1, in <module>
 
   File "<console>", line 1, in <module>
 
TypeError: sequence index must be integer, not 'slice'
 
TypeError: sequence index must be integer, not 'slice'
 +
 +
# Convert to list from xrange object.
 
relax> y=list(range(10))
 
relax> y=list(range(10))
 
relax> print y[:3]
 
relax> print y[:3]
Line 64: Line 73:
 
</source>
 
</source>
  
== Change bug ==
+
== Change bug in dateutil.rrule ==
 +
The recommended way is to update your version of the '''python-dateutil''' package.
 +
 
 +
<source lang="bash">
 +
sudo pip install python-dateutil --upgrade
 +
</source>
 +
 
 +
If you by some means need to stay with the current versions, you can try.
 
<source lang="bash">
 
<source lang="bash">
 
bash
 
bash
 
MFILE=`python -c "import dateutil.rrule; print(dateutil.rrule.__file__)"`
 
MFILE=`python -c "import dateutil.rrule; print(dateutil.rrule.__file__)"`
 
echo $MFILE
 
echo $MFILE
 
+
sudo sed -i -e 's/range(1,30), range(1,31), range(1,32)/list(range(1,30)), list(range(1,31)), list(range(1,32))/g' $MFILE
 +
sudo sed -i -e 's/range(-29,0), range(-30,0), range(-31,0)/list(range(-29,0)), list(range(-30,0)), list(range(-31,0))/g' $MFILE
 
</source>
 
</source>
  
 
Test if it worked
 
Test if it worked
 
<source lang="bash">
 
<source lang="bash">
$ relax
+
cat <<EOF > relax_test.py
relax> from pylab import *
+
from pylab import *
Traceback (most recent call last):
+
 
  File "<console>", line 1, in <module>
+
t = arange(0.0, 2.0, 0.01)
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/pylab.py", line 1, in <module>
+
s = sin(2*pi*t)
    from matplotlib.pylab import *
+
plot(t, s)
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/pylab.py", line 221, in <module>
+
 
    from matplotlib import mpl  # pulls in most modules
+
xlabel('time (s)')
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/mpl.py", line 3, in <module>
+
ylabel('voltage (mV)')
    from matplotlib import axes
+
title('About as simple as it gets, folks')
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py", line 19, in <module>
+
grid(True)
    import matplotlib.dates as mdates
+
show()
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/dates.py", line 119, in <module>
+
EOF
    from dateutil.rrule import rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY, \
+
 
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/dateutil/rrule.py", line 26, in <module>
+
relax relax_test.py
    MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
 
TypeError: unsupported operand type(s) for +: 'xrange' and 'xrange'
 
 
</source>
 
</source>
  
 
== See also ==
 
== See also ==
 
[[Category:matplotlib]]
 
[[Category:matplotlib]]

Latest revision as of 17:45, 19 October 2015

Background

When you create a range in relax, it is created as an xrange object.
This is due to memory issues, which you can read about here.

You cannot by default slice through xrange objects.

The dateutil.rrule package (version 1.5) used in matplotlib/pylab creates some list, which it expects it can slice through.
dateutil.rrule package (version 2.2) does not have this problem.

But relax will create these as xrange which is not-sliceable.

Let's try it out.

USER@MACHINE: $ python

>>> x=range(10)
>>> type(x)
<type 'list'>
>>> print x[:3]
[0, 1, 2]

# Lets create an xrange object.
>>> y=xrange(10)
>>> type(y)
<type 'xrange'>
>>> print y[:3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence index must be integer, not 'slice'

Now let's try in relax.

USER@MACHINE: $ relax

relax> x=range(10)
relax> type(x)
<type 'xrange'>
relax> print x[:3]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: sequence index must be integer, not 'slice'

# Convert to list from xrange object.
relax> y=list(range(10))
relax> print y[:3]
[0, 1, 2]
relax>

The error when importing matplotlib / pyplot

USER@MACHINE: $ relax

relax> from pylab import *
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/pylab.py", line 1, in <module>
    from matplotlib.pylab import *
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/pylab.py", line 221, in <module>
    from matplotlib import mpl  # pulls in most modules
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/mpl.py", line 3, in <module>
    from matplotlib import axes
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py", line 19, in <module>
    import matplotlib.dates as mdates
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/dates.py", line 119, in <module>
    from dateutil.rrule import rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY, \
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/dateutil/rrule.py", line 26, in <module>
    MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
TypeError: unsupported operand type(s) for +: 'xrange' and 'xrange'

Change bug in dateutil.rrule

The recommended way is to update your version of the python-dateutil package.

sudo pip install python-dateutil --upgrade

If you by some means need to stay with the current versions, you can try.

bash
MFILE=`python -c "import dateutil.rrule; print(dateutil.rrule.__file__)"`
echo $MFILE
sudo sed -i -e 's/range(1,30), range(1,31), range(1,32)/list(range(1,30)), list(range(1,31)), list(range(1,32))/g' $MFILE
sudo sed -i -e 's/range(-29,0), range(-30,0), range(-31,0)/list(range(-29,0)), list(range(-30,0)), list(range(-31,0))/g' $MFILE

Test if it worked

cat <<EOF > relax_test.py
from pylab import *

t = arange(0.0, 2.0, 0.01)
s = sin(2*pi*t)
plot(t, s)

xlabel('time (s)')
ylabel('voltage (mV)')
title('About as simple as it gets, folks')
grid(True)
show()
EOF

relax relax_test.py

See also