Skip to content

Range bug fix for pcolor and pcolormesh #1314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 19, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions lib/matplotlib/axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7364,6 +7364,20 @@ def pcolor(self, *args, **kwargs):

x = X.compressed()
y = Y.compressed()

# Transform from native to data coordinates?
t = collection._transform
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be None? In some other artists it can, but perhaps not here...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the None case is handled by the next line, no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The None case is handled in exactly the same way as it was previously.

if (not isinstance(t, mtransforms.Transform)
and hasattr(t, '_as_mpl_transform')):
t = t._as_mpl_transform(self.axes)

if t and any(t.contains_branch_seperately(self.transData)):
trans_to_data = t - self.transData
pts = np.vstack([x, y]).T.astype(np.float)
transformed_pts = trans_to_data.transform(pts)
x = transformed_pts[..., 0]
y = transformed_pts[..., 1]

minx = np.amin(x)
maxx = np.amax(x)
miny = np.amin(y)
Expand Down Expand Up @@ -7490,6 +7504,19 @@ def pcolormesh(self, *args, **kwargs):
collection.autoscale_None()

self.grid(False)

# Transform from native to data coordinates?
t = collection._transform
if (not isinstance(t, mtransforms.Transform)
and hasattr(t, '_as_mpl_transform')):
t = t._as_mpl_transform(self.axes)

if t and any(t.contains_branch_seperately(self.transData)):
trans_to_data = t - self.transData
pts = np.vstack([X, Y]).T.astype(np.float)
transformed_pts = trans_to_data.transform(pts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only problem with this (and the fix that I implemented), is that the result of transform could be NaN/Inf. It could be fixed in this PR, or we could do it for 1.3 - I will leave that call to whomsoever merges this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pelson Under what circumstances would this case occur?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try uncommenting the set_?lim calls and the data is not put in the correct range.

import matplotlib.pyplot as plt
import numpy as np


import matplotlib.transforms as mtrans


class div(mtrans.Transform):
    input_dims = 2
    output_dims = 2
    has_inverse = False

    def transform_non_affine(self, points):
        new_points = points.copy()
        new_points[:, 1] = 1/new_points[:, 1]
        return new_points

ax = plt.axes()
npts = 21
xs = np.linspace(-5, 10, npts)
ys = np.linspace(0, 5, npts)
xs, ys = np.meshgrid(xs, ys)
data = xs**2 + ys**2

plt.contourf(xs, ys, data, transform=div() + ax.transData)

ax.set_xlim([-6, 11])
ax.set_ylim([0, 5])

plt.show()

Changing the transform to fix inf points will solve the issue:

    def transform_non_affine(self, points):
        new_points = points.copy()
        new_points[:, 1] = 1/new_points[:, 1]
        new_points[new_points == np.inf] = 10
        return new_points

This means, if inf/nan is ignored at the level that this PR fixes, then we will get the "correct" limits.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, by range you mean the x/y range, not the "z" range.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, even with @bblay's fix, the data is still not put in the correct range...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind; I was being retarded.

X = transformed_pts[..., 0]
Y = transformed_pts[..., 1]

minx = np.amin(X)
maxx = np.amax(X)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading