Plotly: How to sort plot by ratio of two variables?

Viewed 328

I made a bar plot where x is the same but with two different y's.

#plot optimazied and actual time difference
import plotly.graph_objects as go
from plotly.offline import iplot
from plotly.subplots import make_subplots

# set up plotly figure
fig = make_subplots(1,1)

# add first bar trace at row = 1, col = 1
fig.add_trace(go.Bar(x=models, y=df['OT'],
                     name='Standard time',
                     marker_color = 'green',
                     opacity=0.4,
                     marker_line_color='rgb(8,48,107)',
                     marker_line_width=2),
                     row = 1, col = 1)

fig.add_trace(go.Bar(x=models, y=df['HP'],
                     name='Under Process time',
                     marker_color = 'red',
                     opacity=0.4,
                     marker_line_color='rgb(8,48,107)',
                     marker_line_width=2),
                     row = 1, col = 1)

fig.update_layout(barmode='group', xaxis_tickangle=-45, xaxis={'categoryorder':'total descending'})
fig.update_xaxes(type='category')
fig.show()

I want to sort the x axis with respect to the ratio between the two y's.

1 Answers

Without a sample of your dataset, it's hard to tell exactly what you're aiming to do here. But I can show you how I would have done it using a dataframe with som synthetic data. In any case, sorting a plotly plot like this would most likely be easiest done through a sorting of the dataset itself. The snippet below takes a dataset like this:

         dates    Y1    Y2
195 2020-07-14  1014  1044
196 2020-07-15  1016  1036
197 2020-07-16  1006  1026
198 2020-07-17  1005  1025
199 2020-07-18  1007  1025

And then builds a new dataset sorted by a calculated column ratio to get this:

        dates    Y1    Y2     ratio
40 2020-02-10  1036  1005  1.030846
41 2020-02-11  1029   998  1.031062
39 2020-02-09  1030   998  1.032064
47 2020-02-17  1028   994  1.034205
46 2020-02-16  1029   990  1.039394

And then two figures are built using go.Figure() and fig.add_traces(go.Scatter()):

enter image description here

I hope this is what you were looking for. Don't hesitate to let me know if not.

Complete code:

import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
import datetime

pd.set_option('display.max_rows', None)

# data sample
nperiods = 200
np.random.seed(123)
df = pd.DataFrame(np.random.randint(-10, 12, size=(nperiods, 2)),
                  columns=['Y1', 'Y2'])
datelist = pd.date_range(datetime.datetime(2020, 1, 1).strftime('%Y-%m-%d'),periods=nperiods).tolist()
df['dates'] = datelist 
df = df.set_index(['dates'])
df.index = pd.to_datetime(df.index)
df.iloc[0] =1000
df = df.cumsum().reset_index()

df2 = df.copy()

df2['ratio'] = df2['Y1'] / df2['Y2']
df2 = df2.dropna()
df2 = df2.sort_values(by='ratio')
df2

fig1 = go.Figure()
fig1.add_traces(go.Scatter(x=df['dates'], y = df['Y1']))
fig1.add_traces(go.Scatter(x=df['dates'], y = df['Y2']))
fig1.update_layout(title = 'Raw data')
fig1.show()
                
fig2 = go.Figure()
fig2.add_traces(go.Scatter(x=df2['ratio'], y = df2['Y1']))
fig2.add_traces(go.Scatter(x=df2['ratio'], y = df2['Y2']))
fig2.update_layout(title = 'Data sorted by ratio Y1 / Y2')
fig2.show()
Related