Giter Club home page Giter Club logo

streamlit-echarts's Introduction

Streamlit - ECharts

Streamlit App

A Streamlit component to display ECharts.

Install

pip install streamlit-echarts

Usage

This library provides 2 functions to display echarts :

  • st_echarts to display charts from ECharts json options as Python dicts
  • st_pyecharts to display charts from Pyecharts instances

Check out the demo and source code for more examples.

st_echarts example

from streamlit_echarts import st_echarts

options = {
    "xAxis": {
        "type": "category",
        "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    "yAxis": {"type": "value"},
    "series": [
        {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "line"}
    ],
}
st_echarts(options=options)

st_pyecharts example

from pyecharts import options as opts
from pyecharts.charts import Bar
from streamlit_echarts import st_pyecharts

b = (
    Bar()
    .add_xaxis(["Microsoft", "Amazon", "IBM", "Oracle", "Google", "Alibaba"])
    .add_yaxis(
        "2017-2018 Revenue in (billion $)", [21.2, 20.4, 10.3, 6.08, 4, 2.2]
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="Top cloud providers 2018", subtitle="2017-2018 Revenue"
        ),
        toolbox_opts=opts.ToolboxOpts(),
    )
)
st_pyecharts(b)

API

st_echarts API

st_echarts(
    options: Dict
    theme: Union[str, Dict]
    events: Dict[str, str]
    height: str
    width: str
    renderer: str
    map: Map
    key: str
)
  • options : Python dictionary that resembles the JSON counterpart of echarts options. For example the basic line chart in JS :
// JS code
option = {
  xAxis: {
    type: "category",
    data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  },
  yAxis: { type: "value" },
  series: [{ data: [820, 932, 901, 934, 1290, 1330, 1320], type: "line" }],
};

is represented in Python :

# Python code
option = {
    "xAxis": {
        "type": "category",
        "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    "yAxis": { "type": "value" },
    "series": [
        {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "line" }
    ],
}
  • theme : echarts theme. You can specify built-int themes or pass over style configuration as a Python dict.
  • events : Python dictionary which maps an event to a Js function as string. For example :
{
    "click": "function(params) { console.log(params.name) }"
}

will get mapped to :

myChart.on("click", function (params) {
  console.log(params.name);
});

Return values from events are sent back to Python, for example:

option = {
    "xAxis": {
        "type": "category",
        "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    "yAxis": { "type": "value" },
    "series": [
        {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "line" }
    ],
}
events = {
    "click": "function(params) { console.log(params.name); return params.name }",
    "dblclick":"function(params) { return [params.type, params.name, params.value] }"
}
value = st_echarts(option, events=events)
st.write(value)  # shows name on bar click and type+name+value on bar double click

The JS code needs to be a one-liner. You can use Javascript minifiers like https://javascript-minifier.com/ or https://www.minifier.org/ to transform your Javascript code to a one-liner.

  • height / width : size of the div wrapper
  • map : register a map using the dedicated Map class
from streamlit_echarts import Map
with open("USA.json", "r") as f:
    map = Map(
        "USA",
        json.loads(f.read()),
        {
            "Alaska": {"left": -131, "top": 25, "width": 15},
            "Hawaii": {"left": -110, "top": 28, "width": 5},
            "Puerto Rico": {"left": -76, "top": 26, "width": 2},
        },
    )
options = {...}
st_echarts(options, map=map)

You'll find a lot of GeoJSON data inside the source code of echarts-countries-js.

  • renderer : SVG or canvas
  • key : assign a fixed identity if you want to change its arguments over time and not have it be re-created.

st_pyecharts API

def st_pyecharts(
    chart: Base
    theme: Union[str, Dict]
    events: Dict[str, str]
    height: str
    width: str
    renderer: str
    map: Map
    key: str
)
  • chart : Pyecharts instance

The docs for the remaining inputs are the same as its st_echarts counterpart.

Development

Install

  • JS side
cd frontend
npm install
  • Python side
conda create -n streamlit-echarts python=3.7
conda activate streamlit-echarts
pip install -e .

Run

Both webpack dev server and Streamlit need to run for development mode.

  • JS side
cd frontend
npm run start
  • Python side

Demo example is on https://github.com/andfanilo/streamlit-echarts-demo.

git clone https://github.com/andfanilo/streamlit-echarts-demo
cd streamlit-echarts-demo/
streamlit run app.py

Caveats

Theme definition

  • Defining the theme in Pyecharts when instantiating chart like Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT)) does not work, you need to call theme in st_pyecharts(c, theme=ThemeType.LIGHT).

On Javascript functions

This library also provides the JsCode util class directly from pyecharts.

This class is used to indicate javascript code by wrapping it with a specific placeholder. On the custom component side, we parse every value in options looking for this specific placeholder to determine whether a value is a JS function.

As such, if you want to pass JS functions as strings in your options, you should use the corresponding JsCode module to wrap code with this placeholder :

  • In Python dicts representing the JSON option counterpart, wrap any JS string function with streamlit_echarts.JsCode by calling JsCode(function).js_code. It's a smaller version of pyecharts.commons.utils.JsCode so you don't need to install pyecharts to use it.
series: [
    {
        type: 'scatter', // this is scatter chart
        itemStyle: {
            opacity: 0.8
        },
        symbolSize: JsCode("function (val) { return val[2] * 40;}").js_code,
        data: [["14.616","7.241","0.896"],["3.958","5.701","0.955"],["2.768","8.971","0.669"],["9.051","9.710","0.171"],["14.046","4.182","0.536"],["12.295","1.429","0.962"],["4.417","8.167","0.113"],["0.492","4.771","0.785"],["7.632","2.605","0.645"],["14.242","5.042","0.368"]]
    }
]
  • In Pyecharts, use pyecharts.commons.utils.JsCode directly, JsCode automatically calls .js_code when dumping options.
.set_series_opts(
        label_opts=opts.LabelOpts(
            position="right",
            formatter=JsCode(
                "function(x){return Number(x.data.percent * 100).toFixed() + '%';}"
            ),
        )
    )

Note: you need the JS string to be on one-line. You can use Javascript minifiers like https://javascript-minifier.com/ or https://www.minifier.org/ to transform your Javascript code to a one-liner.

st_pyecharts VS using pyecharts with components.html

While this package provides a st_pyecharts method, if you're using pyecharts you can directly embed your pyecharts visualization inside st.html by passing the output of the chart's .render_embed().

from pyecharts.charts import Bar
from pyecharts import options as opts
import streamlit.components.v1 as components

c = (Bar()
    .add_xaxis(["Microsoft", "Amazon", "IBM", "Oracle", "Google", "Alibaba"])
    .add_yaxis('2017-2018 Revenue in (billion $)', [21.2, 20.4, 10.3, 6.08, 4, 2.2])
    .set_global_opts(title_opts=opts.TitleOpts(title="Top cloud providers 2018", subtitle="2017-2018 Revenue"),
                     toolbox_opts=opts.ToolboxOpts())
    .render_embed() # generate a local HTML file
)
components.html(c, width=1000, height=1000)

Using st_pyecharts is still something you would want if you need to change data regularly without remounting the component, check for examples examples/app_pyecharts.py for Chart with randomization example.

Credits

Support me

Buy Me A Coffee

streamlit-echarts's People

Contributors

aarong1 avatar andfanilo avatar brightxml avatar dmracek avatar randyzwitch avatar tconkling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

streamlit-echarts's Issues

Add support for Echarts API

It would be really helpful if somehow the API for some instance can be called from python to update the chart dynamically for instance.

Bump to echart-v5.3

Hi, Is there a plan to update echarts to version 5.3? I want to use the value_formatter to display return rates. Sample code worked in pyecharts:

line.add_xaxis(x_list).add_yaxis(column_name, column_data.tolist(),
                                 label_opts=opts.LabelOpts(is_show=False),
                                 yaxis_index=0 if column_name in left_y_labels else 1,
                                 tooltip_opts={'valueFormatter': JsCode(
                                     "(value) => value === null ? '-' : (value * 100).toFixed(2) + '%'")},
                                 is_symbol_show=False)

New feature request

I absolutely loved using this fantastic library for creating high-quality charts in Streamlit!

I have one more improvement request, if I may. I'm currently using ECharts as part of an internal dashboard for our daily production reports to monitor machine performance. Everything is working smoothly, except for one feature our users are requesting. They want the ability to generate and download some of the charts as PowerPoint files with the click of a button. I've had prior success saving Seaborn charts in PowerPoint from Streamlit, but I'm facing challenges with the ECharts library. It seems that when I render the charts using st_echarts, there is no returned value.

Is it possible to request the addition of a figure-like object that we can use to further process and save these charts? Thank you so much for your help!

small typo on docs front page

I notice a small typo regarding the use of .js_code
The context and proposed fix are outlined in this PR

#49

Thank you for all your outrageous work on this. The package looks fantastic

Best, Aaron

Add suport for st.columns()

Hey!

Is it possible to use this wonderful lib with the st.column() notation in Streamlit?
Tried and returned an error.

Thanks!!

Add wordcloud extension

1、if like this , it donot work
b = (
WordCloud()
.add(series_name="xxx", data_pair=data)
)
st_pyecharts(b)

2、like this, it works
b = (
WordCloud()
.add(series_name="xxx", data_pair=data, word_size_range=[6, 66])
.render_embed()
)
components.html(b, width=1000, height=1000)

st_echarts events function unable to reference chart object

I'm having some trouble referencing the axisareaselected event: axis area selected
I wanted to get access to the parallel chart selections and return it to streamlit for further filtering.
But I am unable to reference the chart object.

How does the js function get mapped? you declare myChart. but I am unable to reference that either
image

working with mapbox

Awesome component! I just wonder is it possible to include mapbox-gl in the frontend dependency, so that the built-in support of mapbox-gl could actually be enabled? I am trying to draw a wind visualization, just like this example, but on mapbox. Thank you in advance!!

Does Pyecharts Map chart need to follow echarts sample

python3.6.3
streamlit 0.82.0
streamlit-echarts 0.3.0

on Pyecharts, the MAP chart can be loaded

from pyecharts.charts import Map
from pyecharts.faker import Faker
from pyecharts import options as opts

demoMap = Map(init_opts=opts.InitOpts(bg_color='white'))
demoMap.add("Demo", [list(z) for z in zip(Faker.country, Faker.values())], "world")
demoMap.render("demo.html")

Using streamlit-echarts, the same cannot load the map but just I can see chart legend in streamlit, just no map is shown nor error msg.

st_pyecharts(chart=demoMap)

Does it need to follow echarts sample, e.g. load JSON file, etc because pyecharts has simplified those geo data already.

There is no issue to load Bar chart and its content in streamlit.

thank you

st_echarts are not visualized in multitabs

Note: published on Stackoverflow

I want a 4-tab page in Streamlit: 2 echarts + 2 plotly.

Why is any echart plot (but the first) not visualized, while plotly's ones are ok?

(The real app needs a Sankey with special features that only Echarts can provide, so using another library (after extensive research) is not feasible: as in this stripped down example, only the first Sankey is visualised, not the next ones, as echarts "forgets" to refresh the visualisation after switching the tab)

import streamlit as st
from streamlit_echarts import st_echarts
import plotly.figure_factory as ff
import numpy as np

tab1, tab2, tab3, tab4 = st.tabs(["echarts_tab1", "echarts_tab2", "plotly_tab3", "plotly_tab4"])

def echarts_random_options():
    return {
        "xAxis": {"type": "category", "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]},
        "yAxis": {"type": "value"},
        "series": [
            {"data": list(np.random.random(size=7) * 800),
             "type": "line"}
        ],
    }

def plotly_random_fig():
    return ff.create_distplot([np.random.randn(200)], ["values"], bin_size=[.1, .25, .5])

with tab1:
    st_echarts(options=echarts_random_options())
    
with tab2:
    st_echarts(options=echarts_random_options())
    
with tab3:
    st.plotly_chart(plotly_random_fig(), use_container_width=True)

with tab4:
    st.plotly_chart(plotly_random_fig(), use_container_width=True)

echarts whit tabs

Hey,

I’m trying to make a line and bar chart using st_echarts and separating them with a st.tabs

However, when the second tab is selected, the chart is not displayed…

tabs_echarts_2

from streamlit_echarts import st_echarts
import streamlit as st

tab1, tab2 = st.tabs(['Line', 'Bar'])

with tab1:
    options = {
    "xAxis": {
        "type": "category",
        "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    },
    "yAxis": {"type": "value"},
    "series": [
        {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "line"}
    ],
    }
    st_echarts(options=options)

with tab2:
    options = {
        "xAxis": {
            "type": "category",
            "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
        },
        "yAxis": {"type": "value"},
        "series": [
            {"data": [820, 932, 901, 934, 1290, 1330, 1320], "type": "bar"}
        ],
    }
    st_echarts(options=options)

echarts view fullscreen

The original drawing of streamlit has full screen display, but it seems that streamlit_echarts does not

Render html from st_echarts (not st_pyecharts)

This package is really great! The st_echarts is even better than pyecharts! Because it is much more versatile, and we can use the echarts.js documentation as reference! Which was the main advantage of using R over Python for echarts. Is it possible to render local html from st_echarts? So we can use it in general not just with streamlit..

Kinds Regards,

Add event back to python

It would be great if events could be sent back to python to add some interactions on graphs

events = {"click": "function(params, echarts) {console.log(params);Streamlit.setComponentValue(params)}"}

something = st_pyecharts(b, events=events)
st.text(something)

I understand that Streamlit object is no longer available after component has been rendered.
May be the onclick could be defined as the default behavior of the component ?

Thanks

Chart Height is constant even when setting its height with in initOpts

charts are outputted in streamlit app in constant size which makes them sometimes unreadable.

c = Line(init_opts=opts.InitOpts(theme=ThemeType.DARK, height='1600px', width='1600px'))

image

unlike the stock visualization components of streamlit, the echarts components doesn't have the 'extend' button which the other components have and enables full screen view of the chart.

I know that this probably a streamlit related issue rather than to this package, however - if there is a way to force the chart height or at least add a full screen view option that will be great.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.