Changes

Jump to navigation Jump to search

Matplotlib dateutil bug

3,566 bytes added, 17:45, 19 October 2015
Forced creation of a TOC - this will improve the formatting on the main page 'Did you know...' section.
__TOC__
 
== Background ==
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.
 
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.
 
Let's try it out.
 
<source lang="python">
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'
</source>
Now let's try in relax.
<source lang="python">
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>
</source>
 
== The error when importing matplotlib / pyplot ==
<source lang="python">
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'
</source>
 
== 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">
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
</source>
 
Test if it worked
<source lang="bash">
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
</source>
== See also ==
[[Category:matplotlib]]
Trusted, Bureaucrats
4,228

edits

Navigation menu