Skip to content

Commit 52d0c7f

Browse files
authored
Merge pull request #5697 from robertoffmoura/rm/fix-step-plot
Convert matplotlib step drawstyles to plotly line shapes
2 parents 1ccd51d + 8eff93a commit 52d0c7f

4 files changed

Lines changed: 35 additions & 0 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
88
- Fix `mpl_to_plotly` tick marker mirroring, axis positioning, and trace visibility for twinned and overlaid subplots (such as `twinx` and `twiny`) [[#5310](https://github.com/plotly/plotly.py/pull/5310)], with thanks to @robertoffmoura for the contribution!
99
- Fix concurrent first access to lazily initialized graph object properties, which could raise `ValueError("Invalid value")` [[#5691](https://github.com/plotly/plotly.py/pull/5691)], with thanks to @hb1915 for the contribution!
1010
- Fix `mpl_to_plotly` crashing on touching bars (such as `plt.hist`) due to floating-point noise producing negative `bargap` values by clamping `bargap` to `[0, 1]` [[#5696](https://github.com/plotly/plotly.py/pull/5696)], with thanks to @robertoffmoura for the contribution!
11+
- Fix `mpl_to_plotly` drawing step plots with diagonal lines instead of vertical/horizontal step segments by mapping matplotlib step drawstyles (`steps-pre`, `steps-post`, `steps-mid`) to plotly line shapes [[#5697](https://github.com/plotly/plotly.py/pull/5697)], with thanks to @robertoffmoura for the contribution!
1112
- Export tick label colors to the plotly tickfont in `mpl_to_plotly` [[#5716](https://github.com/plotly/plotly.py/pull/5716)], with thanks to @robertoffmoura for the contribution!
1213
- Fix `px.sunburst`, `px.treemap` and `px.icicle` listing sectors in a different order on every run when `path` is used with a Polars DataFrame; sectors now follow their order of first appearance for all dataframe backends [[#5766](https://github.com/plotly/plotly.py/pull/5766)], with thanks to @Irahan2 for the contribution!
1314

‎plotly/matplotlylib/mpltools.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,23 @@ def get_bar_gap(bar_starts, bar_ends, tol=1e-10):
275275
return min(max(gap0 / bar_delta, 0.0), 1.0)
276276

277277

278+
DRAWSTYLE_SHAPE_MAP = {
279+
"steps": "vh",
280+
"steps-pre": "vh",
281+
"steps-post": "hv",
282+
"steps-mid": "hvh",
283+
}
284+
285+
286+
def convert_drawstyle(drawstyle):
287+
"""Convert a matplotlib line drawstyle to a plotly line shape.
288+
289+
Matplotlib draws steps as vertical/horizontal segments; plotly's
290+
``line.shape`` expresses the same via "vh", "hv" and "hvh".
291+
"""
292+
return DRAWSTYLE_SHAPE_MAP.get(drawstyle)
293+
294+
278295
def convert_rgba_array(color_list):
279296
clean_color_list = list()
280297
for c in color_list:

‎plotly/matplotlylib/renderer.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ def draw_marked_line(self, **props):
451451
color=color,
452452
width=props["linestyle"]["linewidth"],
453453
dash=mpltools.convert_dash(props["linestyle"]["dasharray"]),
454+
shape=mpltools.convert_drawstyle(props["linestyle"]["drawstyle"]),
454455
)
455456
else:
456457
shape = dict(

‎plotly/matplotlylib/tests/test_renderer.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ def test_no_fake_legend_shapes_with_native_legend():
3737
assert len(plotly_fig.layout.annotations) == 0
3838

3939

40+
def test_drawstyle_maps_to_line_shape():
41+
cases = {
42+
"steps-pre": "vh",
43+
"steps": "vh",
44+
"steps-post": "hv",
45+
"steps-mid": "hvh",
46+
}
47+
for drawstyle, shape in cases.items():
48+
fig, ax = plt.subplots()
49+
ax.plot([0, 1, 2], [0, 1, 0], drawstyle=drawstyle)
50+
51+
plotly_fig = tls.mpl_to_plotly(fig)
52+
53+
assert plotly_fig.data[0].line.shape == shape
54+
55+
4056
def test_legend_disabled_when_no_matplotlib_legend():
4157
"""Test that legend is not enabled when no matplotlib legend is present."""
4258
fig, ax = plt.subplots()

0 commit comments

Comments
 (0)