Streaming example

A question here on discourse got me started on Streaming.

This is a simple example but so powerful. This a quick and dirty implementation. Don’t yet know how to do this in the best way.

Wanted to share because I have not seen so many examples of streaming with Panel yet.

I don’t understand every detail. If you want to understand it check out the reference guide https://panel.holoviz.org/reference/panes/Streamz.html#panes-gallery-streamz. This example is very much inspired by that.

import numpy as np
import altair as alt
import pandas as pd
import panel as pn
from streamz.dataframe import DataFrame as sDataFrame
alt.renderers.set_embed_options(theme='dark')

df = sDataFrame(example=pd.DataFrame({'y': []}, index=pd.DatetimeIndex([])))

echarts_panel = pn.pane.ECharts(theme="dark")

def line_plot(data):
    data = pd.concat(data).reset_index()
    echarts_panel.object = {
        "xAxis": {
            "type": 'category',
            "data": list(data.index.values)
        },
        "yAxis": {
            "type": 'value'
        },
        "series": [{
            "data": list(data["y"]),
            "type": 'line',
            "showSymbol": False,
            "hoverAnimation": False,
        },
        ],
        "responsive": True
    }
    return echarts_panel
    # return alt.Chart(pd.concat(data).reset_index(), width='container').mark_line().encode(
    #     x='index',
    #     y='y',
    # )

plot_stream = df.cumsum().stream.sliding_window(50).map(line_plot)

plot_pane = pn.pane.Streamz(plot_stream, height=350, sizing_mode="stretch_width", always_watch=True)

for i in range(100):
    df.emit(pd.DataFrame({'y': [np.random.randn()]}, index=pd.DatetimeIndex([pd.datetime.now()])))

def emit():
    df.emit(pd.DataFrame({'y': [np.random.randn()]}, index=pd.DatetimeIndex([pd.datetime.now()])))

pn.state.add_periodic_callback(emit, period=100, count=500)

layout = pn.template.ReactTemplate(
    site="Awesome Panel", title="Streaming w. Echarts", theme=pn.template.react.DarkTheme, row_height=350
)
layout.main[0, 0:6]=plot_pane
layout.main[0, 6:12]=plot_pane.clone()
layout.main[1, 0:6]=plot_pane.clone()
layout.main[1, 6:12]=plot_pane.clone()
layout.servable()
4 Likes

ITS ALIVE!

An IMPROVED VERSION using Echarts, Bokeh/ hvPlot, Vega/ Altair and Plotly can be found at https://awesome-panel.org/streaming-plots. There you can also find links to the latest version of the source code.

1 Like

Nice example @Marc

It looks good in cellphone too

1 Like

I don’t know who that awesome guy who made that work is. Do you @nghenzi?

(thanks :slight_smile:)

There is something about font size on mobile though. If you go to awesome-streamlit.org you can better read that one on mobile because the text is larger. It’s built into the Streamlit template.

But one step at the time. Panel 0.10 is a revolution. It’s so much easier to create something that looks awesome (for nerds :-)). Next step is something that looks awesome for designers and front end people as well. Let’s raise the bar.

2 Likes

Thank you ! but the hard and inspiring work is from philipp and you !

In the last PR recently I added an ID property to each card (“reactcard#”). Then it should be easy to customize the styling of the card

For example,

css = """
.bk-btn-default{background-color: #121212 !important;
                color: white !important;}

.react-grid-item{
   background-color: #545454 !important;
   
 }

 
 .bk-root .choices__list--dropdown .choices__item {
    background-color: #545454;
}


.choices {height:45px;
          overflow-y: auto;}

.choices__inner {height:45px; overflow-y: auto;}

#reactcard4 {border: 5px solid #6b5b95;
padding: 10px;
           padding-top: 20px !important;}

#reactcard3 {overflow: auto;}

            """
pn.extension(raw_css=[css])

you get something like this. This solve the problem when you put a not responsive table too.

the dark theme has no background color, wtih .react-grid-item you can choose a background color to every card.

I do not know, but maybe when you have text there is a solution here to change font size

https://www.w3schools.com/howto/howto_css_responsive_text.asp

1 Like

Thanks @nghenzi.

At some stage we should all sit together and think about version 2 of the templates. I think

  • The properties of the Templates should be similar. If you know one you should be able quickly switch and use another.
  • The golden and react Templates are not really templates. They could just as well be Vanilla, Bootstrap or Material Templates with the golden or react layout. And more layouts could be added in the future.
  • There is still an issue that it is too difficult to “wrap” your app into an external framework like Bootstrap, Material, Shoelace or Fast. Or use widgets styled using that framework. There are different ways to make this easier.
    • Document and showcase more examples of custom templates
    • Make it easier to take a BasicTemplate and customize. Maybe by refactoring, documenting or showcasing how to do this.
    • Make it easier to wrap panels into external html. See https://github.com/holoviz/panel/pull/1343
    • Implement those components as Bokeh Extensions. See awesome-panel-extensions for examples. This takes time though.
    • Actually support something like Paulopes components. That would be the most powerful solution https://github.com/paulopes/panel-components. But it also needs a way to setup bidirectional communication. I’ve been working on that via the WebComponent and via the DataModel
  • Make it easier to style the apps. Right now it’s really, really nitty griddy. Just styling the different button_type’s takes time. Not to say DataFrame, Code Markdown, Plots, … Frameworks like Material and Fast sets a small collection of ::root css variables that the user can override and change. Then the rest is automatically calculated and updated.

I would really, really like to understand how @philippjfr thinks about this one day. I think this is the major challenge to solve for Panel technically.

Paulopes Components

I have contributed an example use case of Paulopes components here https://github.com/paulopes/panel-components/blob/master/examples/fast_hello_world.py

image

which looks like below.

Data Model

1 Like