Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0fa00ef

Browse filesBrowse files
committed
Merge upstream master.
2 parents 49d2cf1 + 77ccc82 commit 0fa00ef
Copy full SHA for 0fa00ef

File tree

Expand file treeCollapse file tree

8 files changed

+116
-13
lines changed
Filter options
Expand file treeCollapse file tree

8 files changed

+116
-13
lines changed

‎lib/matplotlib/figure.py

Copy file name to clipboardExpand all lines: lib/matplotlib/figure.py
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,14 @@ def fixitems(items):
785785
# to tuples for the key
786786
ret = []
787787
for k, v in items:
788-
if iterable(v):
788+
# some objects can define __getitem__ without being
789+
# iterable and in those cases the conversion to tuples
790+
# will fail. So instead of using the iterable(v) function
791+
# we simply try and convert to a tuple, and proceed if not.
792+
try:
789793
v = tuple(v)
794+
except Exception:
795+
pass
790796
ret.append((k, v))
791797
return tuple(ret)
792798

‎lib/matplotlib/image.py

Copy file name to clipboardExpand all lines: lib/matplotlib/image.py
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,11 @@ def __init__(self, ax,
574574
**kwargs
575575
)
576576

577+
def get_window_extent(self, renderer=None):
578+
x0, x1, y0, y1 = self._extent
579+
bbox = Bbox.from_extents([x0, y0, x1, y1])
580+
return bbox.transformed(self.axes.transData)
581+
577582
def make_image(self, magnification=1.0):
578583
if self._A is None:
579584
raise RuntimeError('You must first set the image'

‎lib/matplotlib/tests/test_figure.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_figure.py
+31Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from nose.tools import assert_equal, assert_true, assert_raises
88
from matplotlib.testing.decorators import image_comparison, cleanup
9+
from matplotlib.axes import Axes
910
import matplotlib.pyplot as plt
1011

1112

@@ -110,6 +111,36 @@ def test_too_many_figures():
110111
assert len(w) == 1
111112

112113

114+
def test_iterability_axes_argument():
115+
116+
# This is a regression test for matplotlib/matplotlib#3196. If one of the
117+
# arguments returned by _as_mpl_axes defines __getitem__ but is not
118+
# iterable, this would raise an execption. This is because we check
119+
# whether the arguments are iterable, and if so we try and convert them
120+
# to a tuple. However, the ``iterable`` function returns True if
121+
# __getitem__ is present, but some classes can define __getitem__ without
122+
# being iterable. The tuple conversion is now done in a try...except in
123+
# case it fails.
124+
125+
class MyAxes(Axes):
126+
def __init__(self, *args, **kwargs):
127+
kwargs.pop('myclass', None)
128+
return Axes.__init__(self, *args, **kwargs)
129+
130+
class MyClass(object):
131+
132+
def __getitem__(self, item):
133+
if item != 'a':
134+
raise ValueError("item should be a")
135+
136+
def _as_mpl_axes(self):
137+
return MyAxes, {'myclass': self}
138+
139+
fig = plt.figure()
140+
ax = fig.add_subplot(1, 1, 1, projection=MyClass())
141+
plt.close(fig)
142+
143+
113144
if __name__ == "__main__":
114145
import nose
115146
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

‎lib/matplotlib/tests/test_image.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_image.py
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,28 @@ def test_bbox_image_inverted():
335335
axes.add_artist(bbox_im)
336336

337337

338+
@cleanup
339+
def test_get_window_extent_for_AxisImage():
340+
# Create a figure of known size (1000x1000 pixels), place an image
341+
# object at a given location and check that get_window_extent()
342+
# returns the correct bounding box values (in pixels).
343+
344+
im = np.array([[0.25, 0.75, 1.0, 0.75], [0.1, 0.65, 0.5, 0.4], \
345+
[0.6, 0.3, 0.0, 0.2], [0.7, 0.9, 0.4, 0.6]])
346+
fig = plt.figure(figsize=(10, 10), dpi=100)
347+
ax = plt.subplot()
348+
ax.set_position([0, 0, 1, 1])
349+
ax.set_xlim(0, 1)
350+
ax.set_ylim(0, 1)
351+
im_obj = ax.imshow(im, extent=[0.4, 0.7, 0.2, 0.9], interpolation='nearest')
352+
353+
fig.canvas.draw()
354+
renderer = fig.canvas.renderer
355+
im_bbox = im_obj.get_window_extent(renderer)
356+
357+
assert_array_equal(im_bbox.get_points(), [[400, 200], [700, 900]])
358+
359+
338360
if __name__=='__main__':
339361
import nose
340362
nose.runmodule(argv=['-s','--with-doctest'], exit=False)

‎lib/matplotlib/tests/test_transforms.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_transforms.py
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,12 @@ def test_bbox_as_strings():
487487
assert_equal(eval(format(getattr(b, k), fmt)), v)
488488

489489

490+
def test_transform_single_point():
491+
t = mtrans.Affine2D()
492+
r = t.transform_affine((1, 1))
493+
assert r.shape == (2,)
494+
495+
490496
@cleanup
491497
def test_log_transform():
492498
# Tests that the last line runs without exception (previously the

‎src/_path.h

Copy file name to clipboardExpand all lines: src/_path.h
+28-1Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vecto
687687
}
688688

689689
template <class VerticesArray, class ResultArray>
690-
void affine_transform(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
690+
void affine_transform_2d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
691691
{
692692
if (vertices.dim(0) != 0 && vertices.dim(1) != 2) {
693693
throw "Invalid vertices array.";
@@ -716,6 +716,33 @@ void affine_transform(VerticesArray &vertices, agg::trans_affine &trans, ResultA
716716
}
717717
}
718718

719+
template <class VerticesArray, class ResultArray>
720+
void affine_transform_1d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
721+
{
722+
if (vertices.dim(0) != 2) {
723+
throw "Invalid vertices array.";
724+
}
725+
726+
double x;
727+
double y;
728+
double t0;
729+
double t1;
730+
double t;
731+
732+
x = vertices(0);
733+
y = vertices(1);
734+
735+
t0 = trans.sx * x;
736+
t1 = trans.shx * y;
737+
t = t0 + t1 + trans.tx;
738+
result(0) = t;
739+
740+
t0 = trans.shy * x;
741+
t1 = trans.sy * y;
742+
t = t0 + t1 + trans.ty;
743+
result(1) = t;
744+
}
745+
719746
template <class BBoxArray>
720747
int count_bboxes_overlapping_bbox(agg::rect_d &a, BBoxArray &bboxes)
721748
{

‎src/_path_wrapper.cpp

Copy file name to clipboardExpand all lines: src/_path_wrapper.cpp
+16-10Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -419,24 +419,30 @@ const char *Py_affine_transform__doc__ = "affine_transform(points, trans)";
419419

420420
static PyObject *Py_affine_transform(PyObject *self, PyObject *args, PyObject *kwds)
421421
{
422-
numpy::array_view<const double, 2> vertices;
422+
PyObject *vertices_obj;
423423
agg::trans_affine trans;
424424

425425
if (!PyArg_ParseTuple(args,
426-
"O&O&:affine_transform",
427-
&vertices.converter,
428-
&vertices,
426+
"OO&:affine_transform",
427+
&vertices_obj,
429428
&convert_trans_affine,
430429
&trans)) {
431430
return NULL;
432431
}
433432

434-
npy_intp dims[] = { vertices.dim(0), 2 };
435-
numpy::array_view<double, 2> result(dims);
436-
437-
CALL_CPP("affine_transform", (affine_transform(vertices, trans, result)));
438-
439-
return result.pyobj();
433+
try {
434+
numpy::array_view<double, 2> vertices(vertices_obj);
435+
npy_intp dims[] = { vertices.dim(0), 2 };
436+
numpy::array_view<double, 2> result(dims);
437+
CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
438+
return result.pyobj();
439+
} catch (py::exception) {
440+
numpy::array_view<double, 1> vertices(vertices_obj);
441+
npy_intp dims[] = { vertices.dim(0) };
442+
numpy::array_view<double, 1> result(dims);
443+
CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
444+
return result.pyobj();
445+
}
440446
}
441447

442448
const char *Py_count_bboxes_overlapping_bbox__doc__ = "count_bboxes_overlapping_bbox(bbox, bboxes)";

‎src/ft2font_wrapper.cpp

Copy file name to clipboardExpand all lines: src/ft2font_wrapper.cpp
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,7 @@ static PyObject *PyFT2Font_get_sfnt_table(PyFT2Font *self, PyObject *args, PyObj
13111311
case 6: {
13121312
#if PY3K
13131313
char pclt_dict[] =
1314-
"{s:(h,h), s:k, s:H, s:H, s:H, s:H, s:H, s:H, s:s, s:y, s:b, s:b, "
1314+
"{s:(h,h), s:k, s:H, s:H, s:H, s:H, s:H, s:H, s:y, s:y, s:b, s:b, "
13151315
"s:b}";
13161316
#else
13171317
char pclt_dict[] =

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.