Difference between revisions of "Matplotlib dateutil bug"
Jump to navigation
Jump to search
(Created page with "== Background == == See also == Category:matplotlib") |
(Forced creation of a TOC - this will improve the formatting on the main page 'Did you know...' section.) |
||
(13 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> | ||
+ | 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 == | == See also == | ||
[[Category:matplotlib]] | [[Category:matplotlib]] |
Latest revision as of 17:45, 19 October 2015
Contents
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