-
-
Notifications
You must be signed in to change notification settings - Fork 525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Django Panel with channels for multi apps #928
Conversation
@stefjunod Thanks again, this is looking great overall! I've left a few comments but would be happy to address them myself. My only other comment is that the market_data.csv is pretty big and we might want to find a different way to ship that file or include only a subset. |
Hi, Another commit with the stockscreener working .... So we have 3 apps:
In pn_model.py class StockScreener(param.Parameterized):
# interface
df = param.DataFrame(precedence=-1)
Index = pn.widgets.MultiSelect()
Rebase = pn.widgets.Checkbox(name='Rebase', value=True)
From = pn.widgets.DateSlider()
... In the pn_app.py I had to refer to each widget separately (ss.Index, ss.From, ss.Rebase): def app(doc):
data_path = os.path.join(os.path.dirname(__file__), 'datasets/market_data.csv')
df = pd.read_csv(data_path, index_col=0, parse_dates=True)
ss = StockScreener(df=df)
row = pn.Row(pn.Column(ss.Index, ss.From, ss.Rebase), ss.update_plot)
row.server_doc(doc) This seems easier than using the widgets =.... For the theming, I have a file in the django project folder themes.py: import holoviews as hv
import panel as pn
def __disable_logo(plot, element):
plot.state.toolbar.logo = None
def plot_themes():
# format
hv.plotting.bokeh.ElementPlot.finalize_hooks.append(__disable_logo)
pn.widgets.DatetimeInput.format = '%d %B %Y'
hv.plotting.bokeh.ElementPlot.bgcolor = "#fbfcfc"
hv.plotting.bokeh.ElementPlot.gridstyle = {"grid_line_alpha": 0.6, "grid_line_dash": 'dashed'}
# hv.Palette.colormaps = 'Blues' NOT WORKING I was not able to set the colormaps of hv plot in the plot_themes(), so I put in settings.py a COLOR_MAP = 'Paired' Then in my pn_model.py I had to import it and use it (not pretty....) from django.conf import settings
import datetime as dt
import panel as pn
import param
import holoviews as hv
import hvplot
import hvplot.pandas
class StockScreener(param.Parameterized):
# interface
df = param.DataFrame(precedence=-1)
Index = pn.widgets.MultiSelect()
Rebase = pn.widgets.Checkbox(name='Rebase', value=True)
From = pn.widgets.DateSlider()
def __init__(self, df, **params):
super(StockScreener, self).__init__(**params)
# init df
self.df = df
self.start_date = dt.datetime(year=df.index[0].year, month=df.index[0].month, day=df.index[0].day)
self.end_date = dt.datetime(year=df.index[-1].year, month=df.index[-1].month, day=df.index[-1].day)
self.col = list(self.df.columns)
# init interface
self.Index = pn.widgets.MultiSelect(name='Index', value=self.col[0:5], options=self.col,
size=min(10, len(self.col)))
self.From = pn.widgets.DateSlider(name='From', start=self.start_date, end=self.end_date, value=self.start_date)
@param.depends('Index.value', 'Rebase.value', 'From.value', watch=True)
def update_plot(self, **kwargs):
unds = list(self.Index.value)
pos = self.df.index.get_loc(self.From.value, method='bfill')
dfp = self.df.iloc[pos:][unds]
if self.Rebase.value:
dfp = 100 * dfp / dfp.iloc[0]
# legend positions
# ['top_right', 'top_left', 'bottom_left', 'bottom_right']
# ['right', 'left', 'top', 'bottom']
return dfp.hvplot(value_label="Level", colormap=settings.COLOR_MAP) # dfp.hvplot().opts(legend_position='top_left', responsive=True) # grid=True, colormap='Paired') Questions ?
Cheers, |
Let me know if you want me to look at that, just describe what you want.
That seems fine although I'll look at cleaning that up.
In theory it's possible but I haven't tried persisting sessions in that way.
Yes, let me know where and I can make those changes. |
hvPlot overrides the defaults from HoloViews so we'd probably have to add a way to override hvPlot defaults. Therefore I think the current answer is no. |
Btw, I really appreciate your efforts here, this is great stuff! |
Seems to work, not sure if it is best practice....
Could be interesting to investigate, but not priority...at least for me
For the change you could look into the gbm app pn_models.py as It may take a while to compute and there is a lot sliders. I will clean everything next week. Have a nice week end. |
Hi, Hopefully we are getting there. Hence my final commit... I was not able to add a button to recalc the gbm app pn_models.py: class GBM(param.Parameterized):
# interface
...
# TODO: Add a button param.Action, pn.widgets.Button... only refresh when onclick
# refresh = pn.widgets.Button(name="refresh", button_type='primary')
# refresh.onclick(update_plot)... does not work yet... Otherwise, it works. Hope this helps, |
Hi, I finally succeeded in getting the refresh button to work. The gbm app refresh the plot only when the refresh button is clicked.
# update the plot for every changes
# @param.depends('mean', 'volatility', 'maturity', 'n_observations', 'n_simulations', watch=True)
# refresh the plot only on button refresh click
@param.depends('refresh.clicks') I left the comment to show the other pattern. Cheers, |
Perfect! Sorry I haven't gotten around to working on this yet. I'm hoping to clean it up and merge it by the end of the week. |
63fcaf5
to
5713a6c
Compare
5713a6c
to
a0041f9
Compare
Codecov Report
@@ Coverage Diff @@
## master #928 +/- ##
==========================================
- Coverage 86% 85.95% -0.05%
==========================================
Files 105 105
Lines 11893 11909 +16
==========================================
+ Hits 10228 10236 +8
- Misses 1665 1673 +8
Continue to review full report at Codecov.
|
Thanks again @stefjunod! Hugely appreciate the effort you've put in here. |
Example use of panel with django for a multi apps / multi panels website
README.md provide a description / tutorial
3 apps:
Each apps has a:
Issues/ Not working: