plot problem

pylab.plot (xaxis, log10 (the_sum)*10)
where xaxis is numpy array, and log10(the_sum)*10 is my own class that is a
valid python sequence (it is a c++ wrapper around boost::ublas), gives:
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/pyplot.py", line 2096, in plot
    ret = gca().plot(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 3277, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 394, in _grab_next_args
    for seg in self._plot_2_args(remaining, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 267, in _plot_2_args
    if is_string_like(tup2[1]):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/cbook.py", line 277, in is_string_like
    try: obj + ''
RuntimeError: check:: failed

If I convert the 2nd arg to array, it works:
   pylab.plot (xaxis, np.array(log10 (the_sum)*10))

Doesn't plot support arbitrary sequences?

Neal Becker wrote:

    pylab.plot (xaxis, log10 (the_sum)*10)
where xaxis is numpy array, and log10(the_sum)*10 is my own class that is a valid python sequence (it is a c++ wrapper around boost::ublas), gives:
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/pyplot.py", line 2096, in plot
    ret = gca().plot(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 3277, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 394, in _grab_next_args
    for seg in self._plot_2_args(remaining, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 267, in _plot_2_args
    if is_string_like(tup2[1]):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/cbook.py", line 277, in is_string_like
    try: obj + ''
RuntimeError: check:: failed

If I convert the 2nd arg to array, it works:
   pylab.plot (xaxis, np.array(log10 (the_sum)*10))

Doesn't plot support arbitrary sequences?

Not *completely* arbitrary, evidently. It has to raise a Python exception when an invalid operation (specifically, adding an empty string) is attempted. Apparently your wrapper is not doing this. This is the duck-typing check for a string that mpl has used from early times.

Eric

Is it possible that this could be better? I'm not sure what's happening here,
but I think it is trying to see if my type can be a string first. It can, but
that's not a good idea in this case. It should correctly support a sequence
(and iterator) protocol. Shouldn't matplotlib try that first?

···

On Friday 16 January 2009, Eric Firing wrote:

Neal Becker wrote:
> pylab.plot (xaxis, log10 (the_sum)*10)
> where xaxis is numpy array, and log10(the_sum)*10 is my own class that is
> a valid python sequence (it is a c++ wrapper around boost::ublas), gives:
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/pyplot.py", line 2096, in plot
> ret = gca().plot(*args, **kwargs)
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/axes.py", line 3277, in plot
> for line in self._get_lines(*args, **kwargs):
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/axes.py", line 394, in _grab_next_args
> for seg in self._plot_2_args(remaining, **kwargs):
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/axes.py", line 267, in _plot_2_args
> if is_string_like(tup2[1]):
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/cbook.py", line 277, in is_string_like
> try: obj + ''
> RuntimeError: check:: failed
>
> If I convert the 2nd arg to array, it works:
> pylab.plot (xaxis, np.array(log10 (the_sum)*10))
>
> Doesn't plot support arbitrary sequences?

Not *completely* arbitrary, evidently. It has to raise a Python
exception when an invalid operation (specifically, adding an empty
string) is attempted. Apparently your wrapper is not doing this. This
is the duck-typing check for a string that mpl has used from early times.

Eric

Neal Becker wrote:

    pylab.plot (xaxis, log10 (the_sum)*10)
where xaxis is numpy array, and log10(the_sum)*10 is my own class that is a valid python sequence (it is a c++ wrapper around boost::ublas), gives:
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/pyplot.py", line 2096, in plot
    ret = gca().plot(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 3277, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 394, in _grab_next_args
    for seg in self._plot_2_args(remaining, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 267, in _plot_2_args
    if is_string_like(tup2[1]):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/cbook.py", line 277, in is_string_like
    try: obj + ''
RuntimeError: check:: failed

If I convert the 2nd arg to array, it works:
   pylab.plot (xaxis, np.array(log10 (the_sum)*10))

Doesn't plot support arbitrary sequences?

Partial correction to my previous post:
is_string_like looks for a TypeError or ValueError to be raised. I suppose we could look for any exception, since your object raises a RuntimeError.

I wonder whether it would be equally effective and more robust if the test were

try: '' + obj

instead of the other way around.

Eric

Neal Becker wrote:

···

On Friday 16 January 2009, Eric Firing wrote:

Neal Becker wrote:

    pylab.plot (xaxis, log10 (the_sum)*10)
where xaxis is numpy array, and log10(the_sum)*10 is my own class that is
a valid python sequence (it is a c++ wrapper around boost::ublas), gives:
File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/pyplot.py", line 2096, in plot
    ret = gca().plot(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 3277, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 394, in _grab_next_args
    for seg in self._plot_2_args(remaining, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 267, in _plot_2_args
    if is_string_like(tup2[1]):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/cbook.py", line 277, in is_string_like
    try: obj + ''
RuntimeError: check:: failed

If I convert the 2nd arg to array, it works:
   pylab.plot (xaxis, np.array(log10 (the_sum)*10))

Doesn't plot support arbitrary sequences?

Not *completely* arbitrary, evidently. It has to raise a Python
exception when an invalid operation (specifically, adding an empty
string) is attempted. Apparently your wrapper is not doing this. This
is the duck-typing check for a string that mpl has used from early times.

Eric

Is it possible that this could be better? I'm not sure what's happening here, but I think it is trying to see if my type can be a string first. It can, but that's not a good idea in this case. It should correctly support a sequence (and iterator) protocol. Shouldn't matplotlib try that first?

No, it really needs to find out if it is a string, and a string is iterable, so a string-specific check is needed.

Eric

IIRC, boost::python translates c++ exceptions to RuntimeError. If true, then
it's a lot easier to fix matplotlib than to fix boost::python wrappers.

···

On Friday 16 January 2009, Eric Firing wrote:

Neal Becker wrote:
> pylab.plot (xaxis, log10 (the_sum)*10)
> where xaxis is numpy array, and log10(the_sum)*10 is my own class that is
> a valid python sequence (it is a c++ wrapper around boost::ublas), gives:
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/pyplot.py", line 2096, in plot
> ret = gca().plot(*args, **kwargs)
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/axes.py", line 3277, in plot
> for line in self._get_lines(*args, **kwargs):
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/axes.py", line 394, in _grab_next_args
> for seg in self._plot_2_args(remaining, **kwargs):
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/axes.py", line 267, in _plot_2_args
> if is_string_like(tup2[1]):
> File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
> x86_64.egg/matplotlib/cbook.py", line 277, in is_string_like
> try: obj + ''
> RuntimeError: check:: failed
>
> If I convert the 2nd arg to array, it works:
> pylab.plot (xaxis, np.array(log10 (the_sum)*10))
>
> Doesn't plot support arbitrary sequences?

Partial correction to my previous post:
is_string_like looks for a TypeError or ValueError to be raised. I
suppose we could look for any exception, since your object raises a
RuntimeError.

I wonder whether it would be equally effective and more robust if the
test were

try: '' + obj

instead of the other way around.

Eric

Neal Becker wrote:

Neal Becker wrote:

    pylab.plot (xaxis, log10 (the_sum)*10)
where xaxis is numpy array, and log10(the_sum)*10 is my own class that is
a valid python sequence (it is a c++ wrapper around boost::ublas), gives:
File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/pyplot.py", line 2096, in plot
    ret = gca().plot(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 3277, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 394, in _grab_next_args
    for seg in self._plot_2_args(remaining, **kwargs):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/axes.py", line 267, in _plot_2_args
    if is_string_like(tup2[1]):
  File "/usr/lib/python2.5/site-packages/matplotlib-0.98.5.2-py2.5-linux-
x86_64.egg/matplotlib/cbook.py", line 277, in is_string_like
    try: obj + ''
RuntimeError: check:: failed

If I convert the 2nd arg to array, it works:
   pylab.plot (xaxis, np.array(log10 (the_sum)*10))

Doesn't plot support arbitrary sequences?

Partial correction to my previous post:
is_string_like looks for a TypeError or ValueError to be raised. I
suppose we could look for any exception, since your object raises a
RuntimeError.

I wonder whether it would be equally effective and more robust if the
test were

try: '' + obj

instead of the other way around.

Eric

IIRC, boost::python translates c++ exceptions to RuntimeError. If true, then it's a lot easier to fix matplotlib than to fix boost::python wrappers.

After poking around a little, I conclude that there is nothing gained by having is_string_like look for particular exceptions, so I will relax that, which should solve your problem with no negative consequences for anything else.

I've committed the change to the 98.5 maintenance branch, but I'm having trouble with svnmerge, so I don't know how long it will take to get it into the trunk.

Eric

···

On Friday 16 January 2009, Eric Firing wrote: