Skip to content

Commit 2cd1530

Browse files
authored
sync mplexporter submodule (#1409)
* sync mplexporter * Fix tests for updated mplexporter * Initialize matplotlib backend once in test_optional __init__.py
1 parent 2dfe6d5 commit 2cd1530

File tree

19 files changed

+129
-95
lines changed

19 files changed

+129
-95
lines changed

Diff for: plotly/matplotlylib/mplexporter/exporter.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import matplotlib
1212
from matplotlib import transforms, collections
13-
13+
from matplotlib.backends.backend_agg import FigureCanvasAgg
1414

1515
class Exporter(object):
1616
"""Matplotlib Exporter
@@ -42,6 +42,8 @@ def run(self, fig):
4242
"""
4343
# Calling savefig executes the draw() command, putting elements
4444
# in the correct place.
45+
if fig.canvas is None:
46+
canvas = FigureCanvasAgg(fig)
4547
fig.savefig(io.BytesIO(), format='png', dpi=fig.dpi)
4648
if self.close_mpl:
4749
import matplotlib.pyplot as plt
@@ -157,13 +159,16 @@ def crawl_legend(self, ax, legend):
157159
# force a large zorder so it appears on top
158160
child.set_zorder(1E6 + child.get_zorder())
159161

162+
# reorder border box to make sure marks are visible
163+
if isinstance(child, matplotlib.patches.FancyBboxPatch):
164+
child.set_zorder(child.get_zorder()-1)
165+
160166
try:
161167
# What kind of object...
162168
if isinstance(child, matplotlib.patches.Patch):
163169
self.draw_patch(ax, child, force_trans=ax.transAxes)
164170
elif isinstance(child, matplotlib.text.Text):
165-
if not (child is legend.get_children()[-1]
166-
and child.get_text() == 'None'):
171+
if child.get_text() != 'None':
167172
self.draw_text(ax, child, force_trans=ax.transAxes)
168173
elif isinstance(child, matplotlib.lines.Line2D):
169174
self.draw_line(ax, child, force_trans=ax.transAxes)
@@ -181,7 +186,8 @@ def draw_line(self, ax, line, force_trans=None):
181186
ax, line.get_xydata(),
182187
force_trans=force_trans)
183188
linestyle = utils.get_line_style(line)
184-
if linestyle['dasharray'] in ['None', 'none', None]:
189+
if (linestyle['dasharray'] is None
190+
and linestyle['drawstyle'] == 'default'):
185191
linestyle = None
186192
markerstyle = utils.get_marker_style(line)
187193
if (markerstyle['marker'] in ['None', 'none', None]

Diff for: plotly/matplotlylib/mplexporter/renderers/base.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import warnings
22
import itertools
33
from contextlib import contextmanager
4+
from distutils.version import LooseVersion
45

56
import numpy as np
7+
import matplotlib as mpl
68
from matplotlib import transforms
79

810
from .. import utils
@@ -189,8 +191,11 @@ def _iter_path_collection(paths, path_transforms, offsets, styles):
189191
"""Build an iterator over the elements of the path collection"""
190192
N = max(len(paths), len(offsets))
191193

192-
if not path_transforms:
193-
path_transforms = [np.eye(3)]
194+
# Before mpl 1.4.0, path_transform can be a false-y value, not a valid
195+
# transformation matrix.
196+
if LooseVersion(mpl.__version__) < LooseVersion('1.4.0'):
197+
if path_transforms is None:
198+
path_transforms = [np.eye(3)]
194199

195200
edgecolor = styles['edgecolor']
196201
if np.size(edgecolor) == 0:
@@ -260,8 +265,8 @@ def draw_path_collection(self, paths, path_coordinates, path_transforms,
260265
# This is a hack:
261266
if path_coordinates == "figure":
262267
path_coordinates = "points"
263-
style = {"edgecolor": utils.color_to_hex(ec),
264-
"facecolor": utils.color_to_hex(fc),
268+
style = {"edgecolor": utils.export_color(ec),
269+
"facecolor": utils.export_color(fc),
265270
"edgewidth": lw,
266271
"dasharray": "10,0",
267272
"alpha": styles['alpha'],

Diff for: plotly/matplotlylib/mplexporter/tests/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import matplotlib
2+
matplotlib.use('Agg')
3+
import matplotlib.pyplot as plt

Diff for: plotly/matplotlylib/mplexporter/tests/test_basic.py

+36-15
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
from ..exporter import Exporter
2-
from ..renderers import FakeRenderer, FullFakeRenderer
3-
41
import matplotlib
5-
matplotlib.use('Agg')
6-
import matplotlib.pyplot as plt
7-
82
import numpy as np
3+
from distutils.version import LooseVersion
4+
from nose.plugins.skip import SkipTest
95
from numpy.testing import assert_warns
106

7+
from ..exporter import Exporter
8+
from ..renderers import FakeRenderer, FullFakeRenderer
9+
from . import plt
10+
1111

1212
def fake_renderer_output(fig, Renderer):
1313
renderer = Renderer()
@@ -128,6 +128,23 @@ def test_path():
128128
closing figure
129129
""")
130130

131+
def test_Figure():
132+
""" if the fig is not associated with a canvas, FakeRenderer shall
133+
not fail. """
134+
fig = plt.Figure()
135+
ax = fig.add_subplot(111)
136+
ax.add_patch(plt.Circle((0, 0), 1))
137+
ax.add_patch(plt.Rectangle((0, 0), 1, 2))
138+
139+
_assert_output_equal(fake_renderer_output(fig, FakeRenderer),
140+
"""
141+
opening figure
142+
opening axes
143+
draw path with 25 vertices
144+
draw path with 4 vertices
145+
closing axes
146+
closing figure
147+
""")
131148

132149
def test_multiaxes():
133150
fig, ax = plt.subplots(2)
@@ -148,24 +165,27 @@ def test_multiaxes():
148165

149166

150167
def test_image():
168+
# Test fails for matplotlib 1.5+ because the size of the image
169+
# generated by matplotlib has changed.
170+
if LooseVersion(matplotlib.__version__) >= LooseVersion('1.5.0'):
171+
raise SkipTest("Test fails for matplotlib version > 1.5.0");
151172
np.random.seed(0) # image size depends on the seed
152-
fig, ax = plt.subplots()
173+
fig, ax = plt.subplots(figsize=(2, 2))
153174
ax.imshow(np.random.random((10, 10)),
154175
cmap=plt.cm.jet, interpolation='nearest')
155-
156176
_assert_output_equal(fake_renderer_output(fig, FakeRenderer),
157177
"""
158178
opening figure
159179
opening axes
160-
draw image of size 2848
180+
draw image of size 1240
161181
closing axes
162182
closing figure
163183
""")
164184

165185

166186
def test_legend():
167187
fig, ax = plt.subplots()
168-
ax.plot([1,2,3], label='label')
188+
ax.plot([1, 2, 3], label='label')
169189
ax.legend().set_visible(False)
170190
_assert_output_equal(fake_renderer_output(fig, FakeRenderer),
171191
"""
@@ -178,10 +198,11 @@ def test_legend():
178198
closing figure
179199
""")
180200

201+
181202
def test_legend_dots():
182203
fig, ax = plt.subplots()
183-
ax.plot([1,2,3], label='label')
184-
ax.plot([2,2,2], 'o', label='dots')
204+
ax.plot([1, 2, 3], label='label')
205+
ax.plot([2, 2, 2], 'o', label='dots')
185206
ax.legend().set_visible(True)
186207
_assert_output_equal(fake_renderer_output(fig, FullFakeRenderer),
187208
"""
@@ -194,14 +215,14 @@ def test_legend_dots():
194215
draw text 'label' None
195216
draw 2 markers
196217
draw text 'dots' None
197-
draw path with 5 vertices
218+
draw path with 4 vertices
198219
closing legend
199220
closing axes
200221
closing figure
201222
""")
202223

224+
203225
def test_blended():
204226
fig, ax = plt.subplots()
205227
ax.axvline(0)
206-
assert_warns(UserWarning, fake_renderer_output, fig, FakeRenderer)
207-
228+
#assert_warns(UserWarning, fake_renderer_output, fig, FakeRenderer)

Diff for: plotly/matplotlylib/mplexporter/tests/test_utils.py

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from numpy.testing import assert_allclose, assert_equal
2-
import matplotlib.pyplot as plt
2+
from . import plt
33
from .. import utils
44

55

@@ -9,3 +9,26 @@ def test_path_data():
99

1010
assert_allclose(vertices.shape, (25, 2))
1111
assert_equal(codes, ['M', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'Z'])
12+
13+
14+
def test_linestyle():
15+
linestyles = {'solid': 'none', '-': 'none',
16+
'dashed': '6,6', '--': '6,6',
17+
'dotted': '2,2', ':': '2,2',
18+
'dashdot': '4,4,2,4', '-.': '4,4,2,4',
19+
'': None, 'None': None}
20+
21+
for ls, result in linestyles.items():
22+
line, = plt.plot([1, 2, 3], linestyle=ls)
23+
assert_equal(utils.get_dasharray(line), result)
24+
25+
26+
def test_axis_w_fixed_formatter():
27+
positions, labels = [0, 1, 10], ['A','B','C']
28+
29+
plt.xticks(positions, labels)
30+
props = utils.get_axis_properties(plt.gca().xaxis)
31+
32+
assert_equal(props['tickvalues'], positions)
33+
assert_equal(props['tickformat'], labels)
34+

0 commit comments

Comments
 (0)