Plotly: How to make a multiple index dropdown option?

ghz 2days ago ⋅ 3 views

I have data with same index number for different timeframe as below

           Time CallOI  PutOI   CallLTP PutLTP  
29500   3:30 PM 502725  554775  343.70  85.50   
29500   3:15 PM 568725  629700  357.15  81.70   
29500   2:59 PM 719350  689850  337.85  95.45   
29500   2:45 PM 786975  641575  360.00  108.35  
29500   2:30 PM 823500  626875  336.50  127.80  
29500   2:15 PM 812450  631800  308.55  143.00  
29500   2:00 PM 974700  617750  389.80  120.00  
29500   1:45 PM 1072675 547100  262.55  186.85  
29500   1:30 PM 1272300 469600  206.85  232.00  
29600   3:30 PM 502725  554775  343.70  85.50   
29600   3:15 PM 568725  629700  357.15  81.70   
29600   2:59 PM 719350  689850  337.85  95.45   
29600   2:45 PM 786975  641575  360.00  108.35  
29600   2:30 PM 823500  626875  336.50  127.80  
29600   2:15 PM 812450  631800  308.55  143.00  
29600   2:00 PM 974700  617750  389.80  120.00  
29600   1:45 PM 1072675 547100  262.55  186.85  
29600   1:30 PM 1272300 469600  206.85  232.00  
29700   3:30 PM 502725  554775  343.70  85.50   
29700   3:15 PM 568725  629700  357.15  81.70   
29700   2:59 PM 719350  689850  337.85  95.45   
29700   2:45 PM 786975  641575  360.00  108.35  
29700   2:30 PM 823500  626875  336.50  127.80  
29700   2:15 PM 812450  631800  308.55  143.00  
29700   2:00 PM 974700  617750  389.80  120.00  
29700   1:45 PM 1072675 547100  262.55  186.85  
29700   1:30 PM 1272300 469600  206.85  232.00  

using below code i have made chart :

subfig = make_subplots(specs=[[{"secondary_y": True}]])

# create two independent figures with px.line each containing data from multiple columns
fig = px.line(df,x='Time', y='Call OI')
fig2 = px.line(df,x='Time', y='Call LTP')

fig2.update_traces(yaxis="y2")

subfig.add_traces(fig.data + fig2.data)
subfig.layout.xaxis.title="Time"
subfig.layout.yaxis.title="OI"
subfig.layout.yaxis2.type="log"
subfig.layout.yaxis2.title="Price"
# recoloring is necessary otherwise lines from fig und fig2 would share each color
# e.g. Linear-, Log- = blue; Linear+, Log+ = red... we don't want this
subfig.for_each_trace(lambda t: t.update(line=dict(color=t.marker.color)))
subfig.show()

Chart

I want dropdown menu which selects different index and the chart data changes accordingly. example if i select from drop down 29600 it shows only data for that index number and also is there a way to flip x axis (time) from left to right. Thanks in advance for any solutions

Answer

You can achieve the desired functionality by adding a dropdown menu that filters the data based on the selected index and flipping the x-axis. Here's how to modify your existing code to meet these requirements:

Steps:

  1. Dropdown Menu for Index Filtering: You'll need to add a updatemenus component to your plot layout. This will allow you to filter the data based on the selected index.
  2. Flipping the X-Axis: You can set the xaxis property to reverse the order of the axis, making the time run from right to left.

Here's the updated code to achieve both:

Updated Code:

import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots

# Sample Data (Replace with your actual DataFrame)
data = {
    'Time': ['3:30 PM', '3:15 PM', '2:59 PM', '2:45 PM', '2:30 PM', '2:15 PM', '2:00 PM', '1:45 PM', '1:30 PM',
             '3:30 PM', '3:15 PM', '2:59 PM', '2:45 PM', '2:30 PM', '2:15 PM', '2:00 PM', '1:45 PM', '1:30 PM',
             '3:30 PM', '3:15 PM', '2:59 PM', '2:45 PM', '2:30 PM', '2:15 PM', '2:00 PM', '1:45 PM', '1:30 PM'],
    'Index': [29500, 29500, 29500, 29500, 29500, 29500, 29500, 29500, 29500,
              29600, 29600, 29600, 29600, 29600, 29600, 29600, 29600, 29600,
              29700, 29700, 29700, 29700, 29700, 29700, 29700, 29700, 29700],
    'CallOI': [502725, 568725, 719350, 786975, 823500, 812450, 974700, 1072675, 1272300,
               502725, 568725, 719350, 786975, 823500, 812450, 974700, 1072675, 1272300,
               502725, 568725, 719350, 786975, 823500, 812450, 974700, 1072675, 1272300],
    'PutOI': [554775, 629700, 689850, 641575, 626875, 631800, 617750, 547100, 469600,
              554775, 629700, 689850, 641575, 626875, 631800, 617750, 547100, 469600,
              554775, 629700, 689850, 641575, 626875, 631800, 617750, 547100, 469600],
    'CallLTP': [343.7, 357.15, 337.85, 360, 336.5, 308.55, 389.8, 262.55, 206.85,
                343.7, 357.15, 337.85, 360, 336.5, 308.55, 389.8, 262.55, 206.85,
                343.7, 357.15, 337.85, 360, 336.5, 308.55, 389.8, 262.55, 206.85],
    'PutLTP': [85.5, 81.7, 95.45, 108.35, 127.8, 143, 120, 186.85, 232,
               85.5, 81.7, 95.45, 108.35, 127.8, 143, 120, 186.85, 232,
               85.5, 81.7, 95.45, 108.35, 127.8, 143, 120, 186.85, 232]
}

df = pd.DataFrame(data)

# Create subplots with secondary y-axis
subfig = make_subplots(specs=[[{"secondary_y": True}]])

# Create two independent figures with px.line each containing data from multiple columns
fig = px.line(df, x='Time', y='CallOI', title="Call OI")
fig2 = px.line(df, x='Time', y='CallLTP', title="Call LTP")

# Update the second figure's y-axis to y2
fig2.update_traces(yaxis="y2")

# Add traces from both figures to the subplot
subfig.add_traces(fig.data + fig2.data)

# Set axis labels
subfig.update_layout(
    xaxis_title="Time",
    yaxis_title="OI",
    yaxis2=dict(
        title="Price",
        type="log"  # Log scale for the second y-axis
    ),
    # Flip x-axis (Time from right to left)
    xaxis=dict(
        tickmode='array',
        tickvals=df['Time'],
        ticktext=df['Time'][::-1],  # Reversed order for x-axis
    ),
    # Dropdown menu to select different index
    updatemenus=[
        {
            'buttons': [
                {
                    'label': str(index),
                    'method': 'relayout',
                    'args': [
                        ['xaxis.range'],
                        {'xaxis.range': [df[df['Index'] == index]['Time'].min(),
                                         df[df['Index'] == index]['Time'].max()]}
                    ]
                }
                for index in df['Index'].unique()
            ],
            'direction': 'down',
            'showactive': True,
            'active': 0,
            'x': 0.1, 'xanchor': 'left',
            'y': 1.15, 'yanchor': 'top'
        }
    ]
)

subfig.update_layout(
    title="Call OI and LTP vs Time",
    template='plotly_dark'
)

# Show the plot
subfig.show()

Key Changes:

  1. Dropdown for Index Selection:

    • Added updatemenus to the layout to create a dropdown menu that allows selecting different indices (e.g., 29500, 29600, etc.).
    • Each index button updates the x-axis range to show only the data for that index.
  2. Flipping the X-Axis:

    • The x-axis is flipped by setting the ticktext to the reversed Time column ([::-1]). This reverses the order of the times on the x-axis, so the times appear from right to left.
  3. Updating the Chart:

    • The updatemenus component is used to control the filtering of the data. When a user selects an index from the dropdown, the chart updates to display only data for that index.

Output:

  • The dropdown will allow you to select different index values (e.g., 29500, 29600).
  • The x-axis will be reversed, displaying time from right to left.