🚀 Gen 5 of the leading AI app deployment platform launches October 6. Click for the livestream.

Ridgeline / Joy plot without transparency

Hi all, I’ve been toying with ridgeline plots (like demonstrated in the examples here: Violin Plots | Python | Plotly).

The adjustment I’ve been trying to make is to remove the transparency and to ensure that the z-order is appropriate (bottom:top :: front:back). This GitHub issue on z-ordering is relevant: feature request: z-ordering parameter for traces · Issue #2345 · plotly/plotly.py · GitHub.

I’ve got my immediate hacky solution here … just wondering if there’s a better way that I haven’t thought of yet or whether there’s something missing in the plotly api for this kind of thing. For this kind of graph, I definitely prefer it without the default transparency that violin plots come with, and z-ordering seems to be a little tricky at the moment (??)

Based off of the demo here:

import plotly.graph_objects as go
from plotly.colors import n_colors
import numpy as np

data = (np.linspace(1, 2, 12)[:, np.newaxis] * np.random.randn(12, 200) +
            (np.arange(12) + 2 * np.random.random(12))[:, np.newaxis])
colors = n_colors('rgb(5, 200, 200)', 'rgb(200, 10, 10)', 12, colortype='rgb')

fig = go.Figure()
for i, (data_line, color) in enumerate(zip(data, colors)):
        go.Violin(x=data_line, line_color='black', name=i, fillcolor=color)

# use negative ... cuz I'm gonna flip things later
fig = fig.update_traces(orientation='h', side='negative', width=3, points=False, opacity=1)
# reverse the (z)-order of the traces
fig.data = fig.data[::-1]
# flip the y axis (negative violin is now positive and traces on the top are now on the bottom)
fig.update_layout(legend_traceorder='reversed', yaxis_autorange='reversed').show()

Produces …

I like it this way more … but it’s a bit fiddly to make!

Just to add a more general summary of what I think the problem is …

  • The z-order of the traces (which is drawn on top of which) is determined by the order of traces in fig.data: fig.data[0] is drawn first and fig.data[-1] is draw last and “on top”.
  • For stacked violin traces, this same order (fig.data) controls the order along the y-axis: fig.data[0] is on the bottom etc.
  • This style of ridgeline plot (which is basically the convention from what I can tell), with high opacity and with the bottom trace “on top” in terms of z-order is impossible if the y-axis stacking and z-order drawing follow the same rule (following the order in fig.data).

My takeaways, if the above is accurate:

  • z-order parameter (like matplotlib) would be awesome to have (see GitHub issue linked above)
  • The lack of control of a violin trace along an axis (y-axis in the case above) feels like a strange limitation or that I’m missing something.