Monday 25 October 2021

cefpython3 with an offline plotly chart

I'm looking for an example of embedding an offline plotly chart within cefpython3. It's my understanding that cefpython3 is built for projects just like this. However, I haven't had any success identifying an example using plotly - which would be helpful to me being new to python. For what it's worth, I'll provide what I've tried:

My code below demonstrates an attempt to combine the example plotly chart from https://dash.plotly.com/layout, with the hello_world.py example from cefpython, found here: https://github.com/cztomczak/cefpython/blob/master/examples/hello_world.py

dashtest.py

from cefpython3 import cefpython as cef
import platform
import sys
#dash (plotly)---------------------
import dash
from dash import dcc
from dash import html
import plotly.express as px
import pandas as pd
#---------------------------------

def main():
    check_versions()
    sys.excepthook = cef.ExceptHook  # To shutdown all CEF processes on error
    cef.Initialize()
    cef.CreateBrowserSync(url="http://127.0.0.1:8050/",
                          window_title="Test")
    DashApp()
    cef.MessageLoop()
    cef.Shutdown()

def check_versions():
    ver = cef.GetVersion()
    print("[dashtest.py] CEF Python {ver}".format(ver=ver["version"]))
    print("[dashtest.py] Chromium {ver}".format(ver=ver["chrome_version"]))
    print("[dashtest.py] CEF {ver}".format(ver=ver["cef_version"]))
    print("[dashtest.py] Python {ver} {arch}".format(
           ver=platform.python_version(),
           arch=platform.architecture()[0]))
    assert cef.__version__ >= "57.0", "CEF Python v57.0+ required to run this"


def DashApp():
    app = dash.Dash()

    # assume you have a "long-form" data frame
    # see https://plotly.com/python/px-arguments/ for more options
    df = pd.DataFrame({
        "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
        "Amount": [4, 1, 2, 2, 4, 5],
        "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
    })

    fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

    app.layout = html.Div(children=[
        html.H1(children='Hello Dash'),

        html.Div(children='''
            Dash: A web application framework for your data.
        '''),

        dcc.Graph(
            id='example-graph',
            figure=fig
        )
    ])

    app.run_server(debug=False)

if __name__ == '__main__':
    main()

Here are my command prompt debug outputs:

[dashtest.py] CEF Python 66.1
[dashtest.py] Chromium 66.0.3359.181
[dashtest.py] CEF 3.3359.1774.gd49d25f
[dashtest.py] Python 3.9.6 64bit

DevTools listening on ws://127.0.0.1:55905/devtools/browser/3e64411d-3a5b-4493-be7b-c12e8498e125
Dash is running on http://127.0.0.1:8050/

 * Serving Flask app 'dashtest' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)

Through debugging efforts, I found that I can get the cefpython3 to load the localhost page of plotly if I run the plotly script first in a separate CMD window. But with this setup, it will only run one or the other - but not both simultaneously in one script.

How can I launch the plotly server; and run cefpython as a single application? Because ultimately, I would have data that I'm reading and writing and refreshing the chart.

Above all - I could be going about this entirely the wrong way. Hopefully I'm just overlooking a basic step here. Thanks for looking.



from cefpython3 with an offline plotly chart

No comments:

Post a Comment