Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Deprecate non-spectral mlab methods
  • Loading branch information
dstansby committed Feb 2, 2018
commit e4114e787c58447b1d415d51118c9dec62ac19d7
4 changes: 2 additions & 2 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5051,7 +5051,7 @@ def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
x, y1, y2 = np.broadcast_arrays(np.atleast_1d(x), y1, y2)

polys = []
for ind0, ind1 in mlab.contiguous_regions(where):
for ind0, ind1 in cbook.contiguous_regions(where):
xslice = x[ind0:ind1]
y1slice = y1[ind0:ind1]
y2slice = y2[ind0:ind1]
Expand Down Expand Up @@ -5232,7 +5232,7 @@ def fill_betweenx(self, y, x1, x2=0, where=None,
y, x1, x2 = np.broadcast_arrays(np.atleast_1d(y), x1, x2)

polys = []
for ind0, ind1 in mlab.contiguous_regions(where):
for ind0, ind1 in cbook.contiguous_regions(where):
yslice = y[ind0:ind1]
x1slice = x1[ind0:ind1]
x2slice = x2[ind0:ind1]
Expand Down
69 changes: 69 additions & 0 deletions lib/matplotlib/cbook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,48 @@ def simple_linear_interpolation(a, steps):
.reshape((len(x),) + a.shape[1:]))


def less_simple_linear_interpolation(x, y, xi, extrap=False):
Copy link
Contributor

Choose a reason for hiding this comment

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

Would https://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html not be good enough? Sorry to give you more work... :-)

Copy link
Member Author

Choose a reason for hiding this comment

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

Don't worry, I'm taking this in small steps anyway since it's only going to go in 2.2 anyway. I'll have a go and see if it works.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not a simple drop in, so I think I'll leave it as is in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

I deprecated this in mlab, so I guess it can stay there...

Copy link
Member Author

Choose a reason for hiding this comment

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

As in I should move it back to mlab in this PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes

"""
This function provides simple (but somewhat less so than
:func:`cbook.simple_linear_interpolation`) linear interpolation.
:func:`simple_linear_interpolation` will give a list of point
between a start and an end, while this does true linear
interpolation at an arbitrary set of points.

This is very inefficient linear interpolation meant to be used
only for a small number of points in relatively non-intensive use
cases. For real linear interpolation, use scipy.
"""
x = np.asarray(x)
y = np.asarray(y)
xi = np.atleast_1d(xi)

s = list(y.shape)
s[0] = len(xi)
yi = np.tile(np.nan, s)

for ii, xx in enumerate(xi):
bb = x == xx
if np.any(bb):
jj, = np.nonzero(bb)
yi[ii] = y[jj[0]]
elif xx < x[0]:
if extrap:
yi[ii] = y[0]
elif xx > x[-1]:
if extrap:
yi[ii] = y[-1]
else:
jj, = np.nonzero(x < xx)
jj = max(jj)

yi[ii] = (y[jj] +
(xx - x[jj]) / (x[jj + 1] - x[jj]) *
(y[jj + 1] - y[jj]))

return yi


@deprecated('2.1', alternative='shutil.rmtree')
def recursive_remove(path):
if os.path.isdir(path):
Expand Down Expand Up @@ -1952,6 +1994,7 @@ def unmasked_index_ranges(mask, compressed=True):
ls_mapper_r = {v: k for k, v in six.iteritems(ls_mapper)}


@deprecated('2.2')
def align_iterators(func, *iterables):
"""
This generator takes a bunch of iterables that are ordered by func
Expand Down Expand Up @@ -1996,6 +2039,32 @@ def __call__(self, key):
break


def contiguous_regions(mask):
"""
Return a list of (ind0, ind1) such that mask[ind0:ind1].all() is
True and we cover all such regions
"""
mask = np.asarray(mask, dtype=bool)

if not mask.size:
return []

# Find the indices of region changes, and correct offset
idx, = np.nonzero(mask[:-1] != mask[1:])
idx += 1

# List operations are faster for moderately sized arrays
idx = idx.tolist()

# Add first and/or last index if needed
if mask[0]:
idx = [0] + idx
if mask[-1]:
idx.append(len(mask))

return list(zip(idx[::2], idx[1::2]))
Copy link
Contributor

Choose a reason for hiding this comment

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

I bet the fastest (not that it necessarily matters) is either to return an iterator using itertools.chain and itertools.islice, or to preallocate the result as an appropriately sized array.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a function I've just directly copied across from mlab to cbook because it's used in 2 different places in Matplotlib

(sorry, I'm kind of dumping stuff as I work on it here, will remove the WIP bit of the title when I think it's all done)

Copy link
Contributor

Choose a reason for hiding this comment

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

no worries, I'm also just dumping my thoughts here and there :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Couldn't get my head around how to make this work so I think I'll leave it for this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

np.column_stack([idxs[::2], idxs[1::2]]) should work well.



def is_math_text(s):
# Did we find an even number of non-escaped dollar signs?
# If so, treat is as math text.
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import numpy as np
import matplotlib as mpl
from . import (_path, artist, cbook, cm, colors as mcolors, docstring,
lines as mlines, mlab, path as mpath, transforms)
lines as mlines, path as mpath, transforms)

CIRCLE_AREA_FACTOR = 1.0 / np.sqrt(np.pi)

Expand Down Expand Up @@ -1040,7 +1040,7 @@ def span_where(x, ymin, ymax, where, **kwargs):
passed on to the collection.
"""
xranges = []
for ind0, ind1 in mlab.contiguous_regions(where):
for ind0, ind1 in cbook.contiguous_regions(where):
xslice = x[ind0:ind1]
if not len(xslice):
continue
Expand Down
24 changes: 17 additions & 7 deletions lib/matplotlib/contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import matplotlib.font_manager as font_manager
import matplotlib.text as text
import matplotlib.cbook as cbook
import matplotlib.mlab as mlab
import matplotlib.mathtext as mathtext
import matplotlib.patches as mpatches
import matplotlib.texmanager as texmanager
Expand Down Expand Up @@ -377,7 +376,7 @@ def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):
not empty (lc defaults to the empty list if None). *spacing*
is the space around the label in pixels to leave empty.

Do both of these tasks at once to avoid calling mlab.path_length
Do both of these tasks at once to avoid calculating path lengths
multiple times, which is relatively costly.

The method used here involves calculating the path length
Expand All @@ -392,7 +391,7 @@ def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):
hlw = lw / 2.0

# Check if closed and, if so, rotate contour so label is at edge
closed = mlab.is_closed_polygon(slc)
closed = _is_closed_polygon(slc)
if closed:
slc = np.r_[slc[ind:-1], slc[:ind + 1]]

Expand All @@ -401,8 +400,10 @@ def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):

ind = 0

# Path length in pixel space
pl = mlab.path_length(slc)
# Calculate path lengths
pl = np.zeros(slc.shape[0], dtype=float)
dx = np.diff(slc, axis=0)
pl[1:] = np.cumsum(np.hypot(dx[:, 0], dx[:, 1]))
Copy link
Contributor

@anntzer anntzer Dec 6, 2017

Choose a reason for hiding this comment

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

this expression is also going to allocate a temporary array (in cumsum) so you may as well do

np.row_stack([0, np.cumsum(...)])

(or concatenate, basically the same)
(in both cases there's two array allocations (three with dx))

(if we're really worried about that the solution is to use np.cumsum(..., out=...), not that I'm suggesting this here)

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you push these couple of fixes to my branch? I'm not entirely sure how to implement them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you apply

diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py
index 9a14cf8e1..274456fd4 100644
--- a/lib/matplotlib/contour.py
+++ b/lib/matplotlib/contour.py
@@ -405,9 +405,8 @@ class ContourLabeler(object):
             ind = 0
 
         # Calculate path lengths
-        pl = np.zeros(slc.shape[0], dtype=float)
         dx = np.diff(slc, axis=0)
-        pl[1:] = np.cumsum(np.hypot(dx[:, 0], dx[:, 1]))
+        pl = np.concatenate([[0], np.cumsum(np.hypot(*dx.T))])
         pl = pl - pl[ind]
 
         # Use linear interpolation to get points around label
diff --git a/lib/matplotlib/widgets.py b/lib/matplotlib/widgets.py
index 7100626ad..20755683c 100644
--- a/lib/matplotlib/widgets.py
+++ b/lib/matplotlib/widgets.py
@@ -1031,8 +1031,7 @@ class RadioButtons(AxesWidget):
 
         def inside(p):
             pcirc = np.array([p.center[0], p.center[1]])
-            d = pclicked - pcirc
-            return np.sqrt(np.dot(d, d)) < p.radius
+            return np.hypot(*(pclicked - pcirc)) < p.radius
 
         for i, (p, t) in enumerate(zip(self.circles, self.labels)):
             if t.get_window_extent().contains(event.x, event.y) or inside(p):

?

pl = pl - pl[ind]

# Use linear interpolation to get points around label
Expand Down Expand Up @@ -627,7 +628,7 @@ def labels(self, inline, inline_spacing):
# zero in print_label and locate_label. Other than these
# functions, this is not necessary and should probably be
# eventually removed.
if mlab.is_closed_polygon(lc):
if _is_closed_polygon(lc):
slc = np.r_[slc0, slc0[1:2, :]]
else:
slc = slc0
Expand Down Expand Up @@ -688,6 +689,15 @@ def _find_closest_point_on_leg(p1, p2, p0):
return d, pc


def _is_closed_polygon(X):
"""
Tests whether first and last object in a sequence are the same. These are
presumably coordinates on a polygonal curve, in which case this function
Copy link
Member

@story645 story645 Feb 5, 2018

Choose a reason for hiding this comment

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

These are presumably coordinates on a polygonal curve, in which case this function tests if that curve is closed.

Sort of odd construction?

Since these objects are presumed to be coordinates on a polygonal curve, this function tests if the curve is closed.

tests if that curve is closed.
"""
return np.all(X[0] == X[-1])


def _find_closest_point_on_path(lc, point):
"""
lc: coordinates of vertices
Expand All @@ -702,7 +712,7 @@ def _find_closest_point_on_path(lc, point):
xcmin = None
legmin = (None, None)

closed = mlab.is_closed_polygon(lc)
closed = _is_closed_polygon(lc)

# build list of legs before and after this vertex
legs = []
Expand Down
Loading