Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Ridgeline Plot #25

Closed
klausondrag opened this issue Mar 25, 2019 · 9 comments
Closed

Ridgeline Plot #25

klausondrag opened this issue Mar 25, 2019 · 9 comments

Comments

@klausondrag
Copy link

klausondrag commented Mar 25, 2019

Hi. It would be great if there was support for a Ridgeline plot since it's a bit tedious to implement it manually. This has been discussed for plotly before:

It could be introduced as px.ridgeline() or px.violin(ridgeline=True). The latter would be great if the same can be achieved for histograms or scatter plots in general.

For inspiration, you can also have a look at https://www.tensorflow.org/guide/tensorboard_histograms
Nice implementation detail from the link:

Also, you may note that the histogram slices are not always evenly spaced in step count or time. This is because TensorBoard uses reservoir sampling to keep a subset of all the histograms, to save on memory. Reservoir sampling guarantees that every sample has an equal likelihood of being included, but because it is a randomized algorithm, the samples chosen don't occur at even steps.

Another useful thing is the x-axis line across the image for a better comparison across the y axis. The highlight of the x and y axis label don't seem to work in the second link above.

Also note the fade in the color from the back to the front in Tensorboard. On the other hand, in this image from the discussion above https://discourse-cdn-sjc2.com/standard17/uploads/plot/original/2X/e/e671a5ab96b5d911449d4607d1d2c61eced81d35.png you can see that the coloring depends on the x position instead which also offers easy visual guidance. So support for coloring depending on the x or y value would be highly useful.

The y-spacing should ideally be a parameter.

Thanks to @nicolaskruchten for guiding me here.

@nicolaskruchten
Copy link
Contributor

This should now be possible with px.violin(...).update_traces(side="positive", width=2) and then tune width to taste. There's not quite enough padding at the top/bottom of the plot at the moment, but that'll be fixed in the next version 😄

image

@klausondrag
Copy link
Author

Thanks for getting back to this and the quick implementation. I haven't had the time yet to return to this but I'm definitely looking forward to using this.

@Nestak2
Copy link

Nestak2 commented Apr 2, 2020

I would like to use a ridgelin plot in plotly, but unfortunately, from what I see it is bound to using px.violin, making it not applicable to my case - I don't want to plot stacked distributions, just stacked curves. Comparing to the figure by @nicolaskruchten from above I have on the y axis also "day" (Fri, Thur, Sat, Sun) on the x axis I have "humidity" and the plotted curves are values for "temperature". So I have f(x)=temperature(humidity) and I want to plot this function stacked for 4 different days.
@nicolaskruchten Is this doable in plotly?

@nicolaskruchten
Copy link
Contributor

You could use px.line or px.area for that I suspect. If you can share some sample data I might be able to take a look!

@Nestak2
Copy link

Nestak2 commented Apr 3, 2020

@nicolaskruchten Thanks for the advice, I will look now into px.line and px.area. In the meanwhile, if you want to play with my data it is here

@maegul
Copy link

maegul commented Jul 26, 2021

This is nice ... but I've struggled to remove the transparency and ensure that the bottom plot is drawn on top.

I've put a post up in the community (https://community.plotly.com/t/ridgeline-joy-plot-without-transparency/55028?u=maegul), on the hacks I went through to do it (see eg below), but I think it's related to this issue because this stylistic choice is pretty common for ridgeline plots and, I'd say, pretty desirable too.

The z-order issue is also related: plotly/plotly.py#2345

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

np.random.seed(1)
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)):
    fig.add_trace(
        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()

Screen Shot 2021-07-26 at 2 32 46 pm

@maegul
Copy link

maegul commented Jul 29, 2021

This should now be possible with px.violin(...).update_traces(side="positive", width=2) and then tune width to taste. There's not quite enough padding at the top/bottom of the plot at the moment, but that'll be fixed in the next version 😄

image

So I'm having issues with this approach when y-axis or trace identifier or name is not quantitative. In such cases, the width parameter, when provided, forces the violins to be completely flat.

I haven't got a good example ready yet ... but I think it occurs with the y-axis datatype is datetime ... ?

This is presumably, again, a problem at the JS level.

@jleape
Copy link

jleape commented Dec 16, 2021

Loving these plots. I noticed that the violins collapse when using a DateTime column:

df = px.data.gapminder()
df['dt']=pd.to_datetime(df['year'], format='%Y')

px.violin(df, y='dt', x='gdpPercap', orientation='h').update_traces(side='positive', width=3)

ridgeline_dt

Changing the width has no effect. Is this inevitable with a continuous variable?

It's not a huge pain to convert 'dt' to a string, but would be nice to use 'dt' directly.

@tpvasconcelos
Copy link

I ran into this issue in the past and decided to build a little fun side project just for this use-case. I'll plug it here in case it can be of help to anyone that runs across this issue: https://github.com/tpvasconcelos/ridgeplot

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants