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

Skip to content

Commit 9576473

Browse files
committed
Merge remote-tracking branch 'upstream/v1.2.x'
2 parents e6628f8 + 73e3131 commit 9576473

File tree

12 files changed

+837
-61
lines changed

12 files changed

+837
-61
lines changed

lib/matplotlib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,7 @@ def tk_window_focus():
10751075
'matplotlib.tests.test_patches',
10761076
'matplotlib.tests.test_pickle',
10771077
'matplotlib.tests.test_rcparams',
1078+
'matplotlib.tests.test_scale',
10781079
'matplotlib.tests.test_simplification',
10791080
'matplotlib.tests.test_spines',
10801081
'matplotlib.tests.test_text',

lib/matplotlib/contour.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ def _process_args(self, *args, **kwargs):
946946
min = seg.min(axis=0)
947947
max = seg.max(axis=0)
948948
havelimits = True
949+
949950
if havelimits:
950951
self.ax.update_datalim([min, max])
951952
self.ax.autoscale_view(tight=True)
@@ -1291,17 +1292,31 @@ def _process_args(self, *args, **kwargs):
12911292
self.zmax = args[0].zmax
12921293
else:
12931294
x, y, z = self._contour_args(args, kwargs)
1294-
1295+
1296+
_mask = ma.getmask(z)
1297+
if _mask is ma.nomask:
1298+
_mask = None
1299+
C = _cntr.Cntr(x, y, z.filled(), _mask)
1300+
1301+
t = self.ax.transData if self.transform is None else self.transform
1302+
1303+
# if the transform is not trans data, and some part of it
1304+
# contains transData, transform the xs and ys to data coordinates
1305+
if (t != self.ax.transData and
1306+
any(t.contains_branch_seperately(self.ax.transData))):
1307+
trans_to_data = self.transform - self.ax.transData
1308+
pts = (np.vstack([x.flat, y.flat]).T)
1309+
transformed_pts = trans_to_data.transform(pts)
1310+
x = transformed_pts[..., 0]
1311+
y = transformed_pts[..., 1]
1312+
12951313
x0 = ma.minimum(x)
12961314
x1 = ma.maximum(x)
12971315
y0 = ma.minimum(y)
12981316
y1 = ma.maximum(y)
12991317
self.ax.update_datalim([(x0,y0), (x1,y1)])
13001318
self.ax.autoscale_view(tight=True)
1301-
_mask = ma.getmask(z)
1302-
if _mask is ma.nomask:
1303-
_mask = None
1304-
C = _cntr.Cntr(x, y, z.filled(), _mask)
1319+
13051320
self.Cntr = C
13061321

13071322
def _get_allsegs_and_allkinds(self):

lib/matplotlib/scale.py

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
from __future__ import print_function
2-
import textwrap
2+
33
import numpy as np
44
from numpy import ma
5-
MaskedArray = ma.MaskedArray
65

7-
from cbook import dedent
8-
from ticker import NullFormatter, ScalarFormatter, LogFormatterMathtext, Formatter
9-
from ticker import NullLocator, LogLocator, AutoLocator, SymmetricalLogLocator, FixedLocator
10-
from ticker import is_decade
11-
from transforms import Transform, IdentityTransform
6+
from matplotlib.cbook import dedent
7+
from matplotlib.ticker import (NullFormatter, ScalarFormatter,
8+
LogFormatterMathtext)
9+
from matplotlib.ticker import (NullLocator, LogLocator, AutoLocator,
10+
SymmetricalLogLocator)
11+
from matplotlib.transforms import Transform, IdentityTransform
1212
from matplotlib import docstring
1313

14+
1415
class ScaleBase(object):
1516
"""
1617
The base class for all scales.
@@ -31,15 +32,15 @@ def get_transform(self):
3132
Return the :class:`~matplotlib.transforms.Transform` object
3233
associated with this scale.
3334
"""
34-
raise NotImplementedError
35+
raise NotImplementedError()
3536

3637
def set_default_locators_and_formatters(self, axis):
3738
"""
3839
Set the :class:`~matplotlib.ticker.Locator` and
3940
:class:`~matplotlib.ticker.Formatter` objects on the given
4041
axis to match this scale.
4142
"""
42-
raise NotImplementedError
43+
raise NotImplementedError()
4344

4445
def limit_range_for_scale(self, vmin, vmax, minpos):
4546
"""
@@ -51,6 +52,7 @@ def limit_range_for_scale(self, vmin, vmax, minpos):
5152
"""
5253
return vmin, vmax
5354

55+
5456
class LinearScale(ScaleBase):
5557
"""
5658
The default linear scale.
@@ -90,10 +92,12 @@ def _mask_non_positives(a):
9092
return ma.MaskedArray(a, mask=mask)
9193
return a
9294

95+
9396
def _clip_non_positives(a):
9497
a[a <= 0.0] = 1e-300
9598
return a
9699

100+
97101
class LogScale(ScaleBase):
98102
"""
99103
A standard logarithmic scale. Care is taken so non-positive
@@ -115,21 +119,21 @@ class LogTransformBase(Transform):
115119
input_dims = 1
116120
output_dims = 1
117121
is_separable = True
118-
122+
has_inverse = True
123+
119124
def __init__(self, nonpos):
120125
Transform.__init__(self)
121126
if nonpos == 'mask':
122127
self._handle_nonpos = _mask_non_positives
123128
else:
124129
self._handle_nonpos = _clip_non_positives
125130

126-
127131
class Log10Transform(LogTransformBase):
128132
base = 10.0
129133

130-
def transform(self, a):
134+
def transform_non_affine(self, a):
131135
a = self._handle_nonpos(a * 10.0)
132-
if isinstance(a, MaskedArray):
136+
if isinstance(a, ma.MaskedArray):
133137
return ma.log10(a)
134138
return np.log10(a)
135139

@@ -140,9 +144,10 @@ class InvertedLog10Transform(Transform):
140144
input_dims = 1
141145
output_dims = 1
142146
is_separable = True
147+
has_inverse = True
143148
base = 10.0
144149

145-
def transform(self, a):
150+
def transform_non_affine(self, a):
146151
return ma.power(10.0, a) / 10.0
147152

148153
def inverted(self):
@@ -151,9 +156,9 @@ def inverted(self):
151156
class Log2Transform(LogTransformBase):
152157
base = 2.0
153158

154-
def transform(self, a):
159+
def transform_non_affine(self, a):
155160
a = self._handle_nonpos(a * 2.0)
156-
if isinstance(a, MaskedArray):
161+
if isinstance(a, ma.MaskedArray):
157162
return ma.log(a) / np.log(2)
158163
return np.log2(a)
159164

@@ -164,9 +169,10 @@ class InvertedLog2Transform(Transform):
164169
input_dims = 1
165170
output_dims = 1
166171
is_separable = True
172+
has_inverse = True
167173
base = 2.0
168174

169-
def transform(self, a):
175+
def transform_non_affine(self, a):
170176
return ma.power(2.0, a) / 2.0
171177

172178
def inverted(self):
@@ -175,9 +181,9 @@ def inverted(self):
175181
class NaturalLogTransform(LogTransformBase):
176182
base = np.e
177183

178-
def transform(self, a):
184+
def transform_non_affine(self, a):
179185
a = self._handle_nonpos(a * np.e)
180-
if isinstance(a, MaskedArray):
186+
if isinstance(a, ma.MaskedArray):
181187
return ma.log(a)
182188
return np.log(a)
183189

@@ -188,9 +194,10 @@ class InvertedNaturalLogTransform(Transform):
188194
input_dims = 1
189195
output_dims = 1
190196
is_separable = True
197+
has_inverse = True
191198
base = np.e
192199

193-
def transform(self, a):
200+
def transform_non_affine(self, a):
194201
return ma.power(np.e, a) / np.e
195202

196203
def inverted(self):
@@ -200,7 +207,8 @@ class LogTransform(Transform):
200207
input_dims = 1
201208
output_dims = 1
202209
is_separable = True
203-
210+
has_inverse = True
211+
204212
def __init__(self, base, nonpos):
205213
Transform.__init__(self)
206214
self.base = base
@@ -209,9 +217,9 @@ def __init__(self, base, nonpos):
209217
else:
210218
self._handle_nonpos = _clip_non_positives
211219

212-
def transform(self, a):
220+
def transform_non_affine(self, a):
213221
a = self._handle_nonpos(a * self.base)
214-
if isinstance(a, MaskedArray):
222+
if isinstance(a, ma.MaskedArray):
215223
return ma.log(a) / np.log(self.base)
216224
return np.log(a) / np.log(self.base)
217225

@@ -222,18 +230,18 @@ class InvertedLogTransform(Transform):
222230
input_dims = 1
223231
output_dims = 1
224232
is_separable = True
225-
233+
has_inverse = True
234+
226235
def __init__(self, base):
227236
Transform.__init__(self)
228237
self.base = base
229238

230-
def transform(self, a):
239+
def transform_non_affine(self, a):
231240
return ma.power(self.base, a) / self.base
232241

233242
def inverted(self):
234243
return LogScale.LogTransform(self.base)
235-
236-
244+
237245
def __init__(self, axis, **kwargs):
238246
"""
239247
*basex*/*basey*:
@@ -316,7 +324,8 @@ class SymmetricalLogTransform(Transform):
316324
input_dims = 1
317325
output_dims = 1
318326
is_separable = True
319-
327+
has_inverse = True
328+
320329
def __init__(self, base, linthresh, linscale):
321330
Transform.__init__(self)
322331
self.base = base
@@ -325,7 +334,7 @@ def __init__(self, base, linthresh, linscale):
325334
self._linscale_adj = (linscale / (1.0 - self.base ** -1))
326335
self._log_base = np.log(base)
327336

328-
def transform(self, a):
337+
def transform_non_affine(self, a):
329338
sign = np.sign(a)
330339
masked = ma.masked_inside(a, -self.linthresh, self.linthresh, copy=False)
331340
log = sign * self.linthresh * (
@@ -344,7 +353,8 @@ class InvertedSymmetricalLogTransform(Transform):
344353
input_dims = 1
345354
output_dims = 1
346355
is_separable = True
347-
356+
has_inverse = True
357+
348358
def __init__(self, base, linthresh, linscale):
349359
Transform.__init__(self)
350360
symlog = SymmetricalLogScale.SymmetricalLogTransform(base, linthresh, linscale)
@@ -354,7 +364,7 @@ def __init__(self, base, linthresh, linscale):
354364
self.linscale = linscale
355365
self._linscale_adj = (linscale / (1.0 - self.base ** -1))
356366

357-
def transform(self, a):
367+
def transform_non_affine(self, a):
358368
sign = np.sign(a)
359369
masked = ma.masked_inside(a, -self.invlinthresh, self.invlinthresh, copy=False)
360370
exp = sign * self.linthresh * (
@@ -434,17 +444,19 @@ def get_transform(self):
434444
return self._transform
435445

436446

437-
438447
_scale_mapping = {
439448
'linear' : LinearScale,
440449
'log' : LogScale,
441450
'symlog' : SymmetricalLogScale
442451
}
452+
453+
443454
def get_scale_names():
444455
names = _scale_mapping.keys()
445456
names.sort()
446457
return names
447458

459+
448460
def scale_factory(scale, axis, **kwargs):
449461
"""
450462
Return a scale class by name.
@@ -462,6 +474,7 @@ def scale_factory(scale, axis, **kwargs):
462474
scale_factory.__doc__ = dedent(scale_factory.__doc__) % \
463475
{'names': " | ".join(get_scale_names())}
464476

477+
465478
def register_scale(scale_class):
466479
"""
467480
Register a new kind of scale.
@@ -470,6 +483,7 @@ def register_scale(scale_class):
470483
"""
471484
_scale_mapping[scale_class.name] = scale_class
472485

486+
473487
def get_scale_docs():
474488
"""
475489
Helper function for generating docstrings related to scales.
@@ -486,6 +500,7 @@ def get_scale_docs():
486500
docs.append("")
487501
return "\n".join(docs)
488502

503+
489504
docstring.interpd.update(
490505
scale = ' | '.join([repr(x) for x in get_scale_names()]),
491506
scale_docs = get_scale_docs().strip(),

lib/matplotlib/testing/decorators.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,17 +244,28 @@ def _image_directories(func):
244244
module_name = func.__module__
245245
if module_name == '__main__':
246246
# FIXME: this won't work for nested packages in matplotlib.tests
247-
import warnings
248247
warnings.warn('test module run as script. guessing baseline image locations')
249248
script_name = sys.argv[0]
250249
basedir = os.path.abspath(os.path.dirname(script_name))
251250
subdir = os.path.splitext(os.path.split(script_name)[1])[0]
252251
else:
253252
mods = module_name.split('.')
254-
assert mods.pop(0) == 'matplotlib'
253+
mods.pop(0) # <- will be the name of the package being tested (in
254+
# most cases "matplotlib")
255255
assert mods.pop(0) == 'tests'
256256
subdir = os.path.join(*mods)
257-
basedir = os.path.dirname(matplotlib.tests.__file__)
257+
258+
import imp
259+
def find_dotted_module(module_name, path=None):
260+
"""A version of imp which can handle dots in the module name"""
261+
res = None
262+
for sub_mod in module_name.split('.'):
263+
res = _, path, _ = imp.find_module(sub_mod, path)
264+
path = [path]
265+
return res
266+
267+
mod_file = find_dotted_module(func.__module__)[1]
268+
basedir = os.path.dirname(mod_file)
258269

259270
baseline_dir = os.path.join(basedir, 'baseline_images', subdir)
260271
result_dir = os.path.abspath(os.path.join('result_images', subdir))
Binary file not shown.

0 commit comments

Comments
 (0)