Bug when zooming on multiple lines separated by None

Hello,

I want to plot multiple lines using matplotlib.pyplot.plot using the None separator: when i zoom or plot lines that go far away from the axis limits, they their direction is changed. I encounter a bug shown by the folowing code:

import matplotlib.pyplot as plt

Single line

x = [0., 1., 1., 0., 0.]
y = [0., 0., 1., 1., 0.]

Multiple lines separated by None

x2 = [0., 1., None ,1., 0.]
y2 = [0., 0., None, 1., 1.]

Let’s plot

fig = plt.figure(0)
plt.clf()
ax = fig.add_subplot(121)
plt.title(‘No zoom’)
plt.xlim([-1, 2])
plt.ylim([-1, 2])
plt.plot(x,y, ‘bo-’, label = ‘This is ok’)
plt.plot(x2,y2, ‘ro-’, label = ‘This is not ok’)
plt.legend()
ax = fig.add_subplot(122)
plt.title(‘With zoom one a corner’)
plt.xlim([-.05, .1])
plt.ylim([.95, 1.05])
plt.plot(x,y, ‘bo-’, label = ‘This is ok’)
plt.plot(x2,y2, ‘ro-’, label = ‘This is not ok’)
plt.legend()
plt.show()

I tried several approaches to solve the problem but never succeeded. I don’t wich to use 2D arrays or LineCollections because this solution is faster and allows the declaration of all lines with a single label and color. Has anyone any idea ?

Regards.

This works for me with 1.2 (not tested before that):

import matplotlib.pyplot as plt
import numpy as np

x = np.array([0, 1, None, 1, 0])
y = np.array([0, 1, None, 0, 1])

plt.plot(x, y)

plt.show()

I get two distinct lines crossing each other at (0.5, 0.5)

HTH,

Hello Phil,

Your example does not trigger the bug because you don’t zoom or specifiy xlim/ylim so that some points are (far) out of the current axis. For example, if you just add these lines to your code, you’ll have it:

import matplotlib.pyplot as plt
import numpy as np
x = np.array([0, 1, None, 1, 0])
y = np.array([0, 1, None, 0, 1])

plt.plot(x, y)

Add this or zoom in the upper left corner.

plt.xlim([0., 0.2])
plt.ylim([.9, 1.1])
plt.show()

Here I see an horizontal line where I should see a 45° tilted line. And the nasty part of this bug is that it only affects lines declared with at least one None in them where continuous lines seem unaffected as shown here:

import matplotlib.pyplot as plt
import numpy as np
x0 = np.array([0, 1])
y0 = np.array([0, 1])
x1 = np.array([1, 0])
y1 = np.array([0, 1])

plt.plot(x0, y0)

plt.plot(x1, y1)

Add this

plt.xlim([0., 0.2])
plt.ylim([.9, 1.1])
plt.show()

I get a 45° line.

Ludovic

ps: I use matplotlib 1.1.1rc (stock version available on repositories) on Xubuntu 12.04 (precise) 64-bit

2012/10/3 Phil Elson <pelson.pub@…287…>

···

This works for me with 1.2 (not tested before that):

import matplotlib.pyplot as plt

import numpy as np

x = np.array([0, 1, None, 1, 0])

y = np.array([0, 1, None, 0, 1])

plt.plot(x, y)

plt.show()

I get two distinct lines crossing each other at (0.5, 0.5)

HTH,

Ludovic Charleux
Assistant Professor
[SYMME / Polytech’ Annecy Chambery

](Polytech Annecy-Chambéry) [Domaine Universitaire, BP 80439

](http://maps.google.com/maps?q=Domaine+Universitaire%2C+BP+80439%2C+Annecy+le+vieux+cedex%2C+F74944%2C+France&hl=en) Annecy le vieux cedex, F74944 France

Work: 33 (0) 4 50 09 65 62
Fax: 33 (0) 4 50 09 65 43
Email: ludovic.charleux@…590…
Professional Profile
See who we know in common
Want a signature like this?

Hello,

I want to plot multiple lines using matplotlib.pyplot.plot using the
None separator: when i zoom or plot lines that go far away from the axis
limits, they their direction is changed. I encounter a bug shown by the
folowing code:

import matplotlib.pyplot as plt

# Single line
x = [0., 1., 1., 0., 0.]
y = [0., 0., 1., 1., 0.]

# Multiple lines separated by None
x2 = [0., 1., None ,1., 0.]
y2 = [0., 0., None, 1., 1.]

I'm surprised this works at all. I don't think we have ever intentionally supported object arrays, which is what you get when you take np.array() of a list with a None in it.

If you want to use this method to make a set of line segments, use np.nan in place of None.

Eric

···

On 2012/10/03 4:24 AM, Charleux Ludovic wrote:

# Let's plot
fig = plt.figure(0)
plt.clf()
ax = fig.add_subplot(121)
plt.title('No zoom')
plt.xlim([-1, 2])
plt.ylim([-1, 2])
plt.plot(x,y, 'bo-', label = 'This is ok')
plt.plot(x2,y2, 'ro-', label = 'This is not ok')
plt.legend()
ax = fig.add_subplot(122)
plt.title('With zoom one a corner')
plt.xlim([-.05, .1])
plt.ylim([.95, 1.05])
plt.plot(x,y, 'bo-', label = 'This is ok')
plt.plot(x2,y2, 'ro-', label = 'This is not ok')
plt.legend()
plt.show()

I tried several approaches to solve the problem but never succeeded. I
don't wich to use 2D arrays or LineCollections because this solution is
faster and allows the declaration of all lines with a single label and
color. Has anyone any idea ?

Regards.

------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

I don’t get this on matplotlib/master (and therefore probably not on 1.2rc2).

I’m pretty sure masked array line plotting was fixed at some point this release cycle (I cannot find the appropriate github issue to link to), so I suggest this is a known bug with 1.1.1 and fixed in 1.2. Just to be clear, I am using the TkAgg backend, and there is a remote possiblity that this bug is backend dependent. Is there any chance you could test this with the latest release candidate?

Many Thanks,

···

On 3 October 2012 17:47, Charleux Ludovic <ludovic.charleux@…287…> wrote:

Hello Phil,

Your example does not trigger the bug because you don’t zoom or specifiy xlim/ylim so that some points are (far) out of the current axis. For example, if you just add these lines to your code, you’ll have it:

import matplotlib.pyplot as plt

import numpy as np

x = np.array([0, 1, None, 1, 0])

y = np.array([0, 1, None, 0, 1])

plt.plot(x, y)

Add this or zoom in the upper left corner.

plt.xlim([0., 0.2])
plt.ylim([.9, 1.1])
plt.show()

Here I see an horizontal line where I should see a 45° tilted line. And the nasty part of this bug is that it only affects lines declared with at least one None in them where continuous lines seem unaffected as shown here:

import matplotlib.pyplot as plt

import numpy as np

x0 = np.array([0, 1])

y0 = np.array([0, 1])
x1 = np.array([1, 0])

y1 = np.array([0, 1])

plt.plot(x0, y0)

plt.plot(x1, y1)

Add this

plt.xlim([0., 0.2])
plt.ylim([.9, 1.1])
plt.show()

I get a 45° line.

Ludovic

ps: I use matplotlib 1.1.1rc (stock version available on repositories) on Xubuntu 12.04 (precise) 64-bit

2012/10/3 Phil Elson <pelson.pub@…287…>

This works for me with 1.2 (not tested before that):

import matplotlib.pyplot as plt

import numpy as np

x = np.array([0, 1, None, 1, 0])

y = np.array([0, 1, None, 0, 1])

plt.plot(x, y)

plt.show()

I get two distinct lines crossing each other at (0.5, 0.5)

HTH,

Ludovic Charleux
Assistant Professor
[SYMME / Polytech’ Annecy Chambery

](Polytech Annecy-Chambéry) [Domaine Universitaire, BP 80439

](http://maps.google.com/maps?q=Domaine+Universitaire%2C+BP+80439%2C+Annecy+le+vieux+cedex%2C+F74944%2C+France&hl=en) Annecy le vieux cedex, F74944 France
Work: 33 (0) 4 50 09 65 62
Fax: 33 (0) 4 50 09 65 43
Email: ludovic.charleux@…83…590…
Professional Profile
See who we know in common
Want a signature like this?

This issue may be dependent upon which version of Numpy one is using. As Eric pointed out, one should be getting an object array if you have a None in the list. On top of that, I wouldn’t be surprised if the different backends handled this object array differently.

As far as I am concerned, using None in the list is the bug and is not only unsupported, but should be actively discouraged. Use NaNs or masked arrays instead.

(and to ward off the inevitable question, I would advise against explicitly checking for object arrays because there are times when it is correct to have such arrays, i.e., python decimal or datetime objects).

Cheers!
Ben Root

···

On Wed, Oct 3, 2012 at 1:02 PM, Phil Elson <pelson.pub@…287…> wrote:

I don’t get this on matplotlib/master (and therefore probably not on 1.2rc2).

I’m pretty sure masked array line plotting was fixed at some point this release cycle (I cannot find the appropriate github issue to link to), so I suggest this is a known bug with 1.1.1 and fixed in 1.2. Just to be clear, I am using the TkAgg backend, and there is a remote possiblity that this bug is backend dependent. Is there any chance you could test this with the latest release candidate?

Many Thanks,

Thanks for your multiple answers. I’ll try the same manipulation with the 1.2 version as soon as possible. Concerning the debate between the use of None and numpy.nan, I tryed both methods before posting and they both lead to the same bug on my version. I’m using the None/numpy.nan trick to plot finite element 2D meshes (Matplotlib allows very neat vectorial plots) and I often adjust xlim/ylim to magnify interesting zones and so this bug is everywhere. I’m not totally sure but I think the bug was not present in the 1.0.x versions I tested before.

Regards.

Ludovic Charleux

2012/10/3 Benjamin Root <ben.root@…1304…>

···

On Wed, Oct 3, 2012 at 1:02 PM, Phil Elson <pelson.pub@…287…> wrote:

I don’t get this on matplotlib/master (and therefore probably not on 1.2rc2).

I’m pretty sure masked array line plotting was fixed at some point this release cycle (I cannot find the appropriate github issue to link to), so I suggest this is a known bug with 1.1.1 and fixed in 1.2. Just to be clear, I am using the TkAgg backend, and there is a remote possiblity that this bug is backend dependent. Is there any chance you could test this with the latest release candidate?

Many Thanks,

This issue may be dependent upon which version of Numpy one is using. As Eric pointed out, one should be getting an object array if you have a None in the list. On top of that, I wouldn’t be surprised if the different backends handled this object array differently.

As far as I am concerned, using None in the list is the bug and is not only unsupported, but should be actively discouraged. Use NaNs or masked arrays instead.

(and to ward off the inevitable question, I would advise against explicitly checking for object arrays because there are times when it is correct to have such arrays, i.e., python decimal or datetime objects).

Cheers!
Ben Root

Thanks for your multiple answers. I'll try the same manipulation with
the 1.2 version as soon as possible. Concerning the debate between the
use of None and numpy.nan, I tryed both methods before posting and they
both lead to the same bug on my version. I'm using the None/numpy.nan
trick to plot finite element 2D meshes (Matplotlib allows very neat
vectorial plots) and I often adjust xlim/ylim to magnify interesting
zones and so this bug is everywhere. I'm not totally sure but I think
the bug was not present in the 1.0.x versions I tested before.

Please--there is *no* None trick. This is not a debate. Please do *not* use None. Use np.nan or a masked array. Unless you go into the lower levels of the api, mpl will convert a floating-point array with nans into a masked array for operations such as auto-scaling.

If you must use an object array (e.g., as Ben notes, if you are using datetime objects--it must be something for which there is a registered converter, because at the plotting level mpl works with floats), then make it a masked array if you need to put gaps in it. If that does not work, then it is a bug in the conversion process. Masked arrays should work for any input type supported by mpl.

Eric

···

On 2012/10/03 8:11 AM, Charleux Ludovic wrote:

Regards.

Ludovic Charleux

2012/10/3 Benjamin Root <ben.root@...1304... <mailto:ben.root@…1304…>>

    On Wed, Oct 3, 2012 at 1:02 PM, Phil Elson <pelson.pub@...287... > <mailto:pelson.pub@…287…>> wrote:

        I don't get this on matplotlib/master (and therefore probably
        not on 1.2rc2).

        I'm pretty sure masked array line plotting was fixed at some
        point this release cycle (I cannot find the appropriate github
        issue to link to), so I suggest this is a known bug with 1.1.1
        and fixed in 1.2. Just to be clear, I am using the TkAgg
        backend, and there is a remote possiblity that this bug is
        backend dependent. Is there any chance you could test this with
        the latest release candidate?

        Many Thanks,

    This issue may be dependent upon which version of Numpy one is
    using. As Eric pointed out, one should be getting an object array
    if you have a None in the list. On top of that, I wouldn't be
    surprised if the different backends handled this object array
    differently.

    As far as I am concerned, using None in the list is the bug and is
    not only unsupported, but should be actively discouraged. Use NaNs
    or masked arrays instead.

    (and to ward off the inevitable question, I would advise against
    explicitly checking for object arrays because there are times when
    it is correct to have such arrays, i.e., python decimal or datetime
    objects).

    Cheers!
    Ben Root

------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options