Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 12 additions & 8 deletions plotly/matplotlylib/renderer.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you think of combining merge_color_and_opacity and _export_color? They seem similar enough and you could deal with converting "none" internally rather than having to add a special case. Additionally, merge_color_and_opacity only gets called once, so we could remove that and replace it with the combined function.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like you could run into the same issue with "none" colors for text. That might be rare, but it could still happen. You can see this on L735 where color=props["style"]["color"] gets passed in without being run through _export_color. I'll let you decide if you make an update in this PR or a future one.

Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ def draw_bar(self, coll):
yaxis="y{0}".format(self.axis_ct),
opacity=trace[0]["alpha"], # TODO: get all alphas if array?
marker=go.bar.Marker(
color=trace[0]["facecolor"], # TODO: get all
color=_export_color(trace[0]["facecolor"]), # TODO: get all
line=dict(width=trace[0]["edgewidth"]),
),
) # TODO ditto
Expand Down Expand Up @@ -398,9 +398,13 @@ def draw_marked_line(self, **props):
self.msg += "... with just markers\n"
mode = "markers"
if props["linestyle"]:
color = mpltools.merge_color_and_opacity(
props["linestyle"]["color"], props["linestyle"]["alpha"]
)
if props["linestyle"]["color"] == "none":
# a fully transparent line; plotly rejects "none" as a color
color = "rgba(0,0,0,0)"
else:
color = mpltools.merge_color_and_opacity(
props["linestyle"]["color"], props["linestyle"]["alpha"]
)
Comment on lines +405 to +407

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This will still throw if the line color has an alpha value, which can happen with mplexporter (because the returned color is rgba and merge_color_and_opacity calls hex_to_rgb). This is a preexisting bug, but you might as well address it since you're in this area.


if props["coordinates"] == "data":
line = go.scatter.Line(
Expand All @@ -420,22 +424,22 @@ def draw_marked_line(self, **props):
if props["coordinates"] == "data":
marker = go.scatter.Marker(
opacity=props["markerstyle"]["alpha"],
color=props["markerstyle"]["facecolor"],
color=_export_color(props["markerstyle"]["facecolor"]),
symbol=mpltools.convert_symbol(props["markerstyle"]["marker"]),
size=props["markerstyle"]["markersize"],
line=dict(
color=props["markerstyle"]["edgecolor"],
color=_export_color(props["markerstyle"]["edgecolor"]),
width=props["markerstyle"]["edgewidth"],
),
)
else:
shape = dict(
opacity=props["markerstyle"]["alpha"],
fillcolor=props["markerstyle"]["facecolor"],
fillcolor=_export_color(props["markerstyle"]["facecolor"]),
symbol=mpltools.convert_symbol(props["markerstyle"]["marker"]),
size=props["markerstyle"]["markersize"],
line=dict(
color=props["markerstyle"]["edgecolor"],
color=_export_color(props["markerstyle"]["edgecolor"]),
width=props["markerstyle"]["edgewidth"],
),
)
Expand Down
22 changes: 22 additions & 0 deletions plotly/matplotlylib/tests/test_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,28 @@ def test_pcolor_rectangles_render():
assert all(len(t.x) >= 4 for t in plotly_fig.data)


def test_boxplot_converts_with_none_marker_facecolor():
"""Boxplot outlier markers use facecolor 'none', which plotly rejects."""
fig, ax = plt.subplots()
ax.boxplot(np.random.randn(100, 4))

plotly_fig = tls.mpl_to_plotly(fig)

assert len(plotly_fig.data) > 0


def test_line_with_none_color_converts():
"""Lines with color='none' use the string 'none' for the line color,
which plotly rejects; it must be exported as a transparent line."""
fig, ax = plt.subplots()
ax.plot([0, 1], [0, 1], color="none")

plotly_fig = tls.mpl_to_plotly(fig)

assert len(plotly_fig.data) == 1
assert plotly_fig.data[0].line.color == "rgba(0,0,0,0)"


def test_eventplot_segments_render():
fig, ax = plt.subplots()
ax.eventplot([np.random.randn(20) for _ in range(5)])
Expand Down
Loading