-
Notifications
You must be signed in to change notification settings - Fork 28
Open
Description
Hi, I would like to contribute an example but I'm lazy to do forking etc. I'm just pasting my code here in hope that one hero will be able to polish it and check in.
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import panel as pn
pn.extension('plotly')
class SessionPanel:
def __init__(self):
self.n = 50
self.df: pd.DataFrame = self._make_df()
self.fig: go.Figure = self._make_fig()
self.plotly_pane: pn.pane.Plotly = pn.pane.Plotly(self.fig, sizing_mode='stretch_both')
# self.plotly_pane.object = self.fig # Example of setting the object directly
def __del__(self):
print("SessionPanel instance is being deleted!!!")
def _make_df(self) -> pd.DataFrame:
dates = pd.date_range("2023-01-01", periods=self.n, freq='min')
price = np.cumsum(np.random.randn(self.n)) + 100
df = pd.DataFrame(dict(
Date=dates,
Open=price + np.random.uniform(-1, 1, self.n),
))
df['Close'] = df['Open'] + np.random.uniform(-2, 2, self.n)
df['High'] = np.maximum(df['Open'], df['Close']) + np.random.uniform(0, 1, self.n)
df['Low'] = np.minimum(df['Open'], df['Close']) - np.random.uniform(0, 1, self.n)
return df
def _make_fig(self) -> go.Figure:
fig = go.Figure(
go.Candlestick(
x=self.df['Date'],
open=self.df['Open'],
high=self.df['High'],
low=self.df['Low'],
close=self.df['Close']
)
)
fig.update_layout(
title="Live Candlestick Chart",
xaxis_rangeslider_visible=False
)
return fig
def update(self):
# Create one new row of data
new_date = self.df['Date'].iloc[-1] + pd.Timedelta(minutes=1)
new_open = self.df['Close'].iloc[-1] + np.random.uniform(-1, 1)
new_close = new_open + np.random.uniform(-2, 2)
new_high = max(new_open, new_close) + np.random.uniform(0, 1)
new_low = min(new_open, new_close) - np.random.uniform(0, 1)
new_row = pd.DataFrame(dict(
Date=[new_date],
Open=[new_open],
High=[new_high],
Low=[new_low],
Close=[new_close]
))
# Slide the window
self.df = pd.concat([self.df.iloc[1:], new_row], ignore_index=True)
# Patch only the changed data in the dict
self.plotly_pane.object['data'][0]['x'] = self.df['Date']
self.plotly_pane.object['data'][0]['open'] = self.df['Open']
self.plotly_pane.object['data'][0]['high'] = self.df['High']
self.plotly_pane.object['data'][0]['low'] = self.df['Low']
self.plotly_pane.object['data'][0]['close'] = self.df['Close']
class DashboardPanel(pn.Column):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Create session-unique data and plot
self.session = SessionPanel()
# Widgets
self.button = pn.widgets.Button(name='Click Me', button_type='primary')
self.select_opt = pn.widgets.Select(name='Market', options=['BTC/USD', 'ETH/USD', 'SPY'])
self.text = pn.widgets.TextInput(name='Notes', placeholder='Enter notes...')
self.button.on_click(self.say_hello)
self.tab1 = pn.Column(
"## Controls",
self.button,
self.select_opt,
)
self.tab2 = pn.Column(
"## Notes",
self.text
)
self.tabs = pn.Tabs(
("Tab 1", self.tab1),
("Tab 2", self.tab2)
)
self.dashboard = pn.Row(
pn.Column("# Left Panel", self.tabs, width=300, sizing_mode='stretch_height'),
pn.Column("# Right Panel", self.session.plotly_pane, sizing_mode='stretch_both'),
sizing_mode='stretch_both'
)
# Add the dashboard layout to this Column
self.append(self.dashboard)
# Add periodic callback for updates (session-specific)
pn.state.add_periodic_callback(self.session.update, period=1000)
# Add session cleanup callback
pn.state.on_session_destroyed(self.on_session_destroyed)
def say_hello(self, event):
print(f"Button clicked! Market: {self.select_opt.value}, Note: {self.text.value}")
def on_session_destroyed(self, session_context):
print("Session ended!")
# Show dashboard based on session
def app():
main_panel: pn.Column = pn.Column()
main_panel.append(DashboardPanel())
return main_panel
app().servable()
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
