Streamlit-echarts

For everybody looking for a simpler way for bi-directional communication from EChart events (JS) back to python.

events = {
   "click": "function(p){console.log(p); delete p.event; window.parent.postMessage({isStreamlitMessage:!0,type:'streamlit:setComponentValue','value':p},'*');}"
} 
r = st_pyecharts(c,  width=9000, height=640, events=events, key='chart')
st.write(json.dumps(r))
  • Don’t forget to assign the “key” parameter, otherwise, st_pyecharts will not return any value.
1 Like

This is exactly what I came here for. Thank you for posting it. Excited to try it out.

1 Like

Thank You! This is really useful.

I would really appreciate if Streamlit-echarts will be maintained in future. It is a killer component, and it would be great if streamlit can incorporate echarts like plotly and provide support for it.

Hi, and thank you for the beauty of charts in Streamlit! I am trying to expand the graph to display more values on the y-axis (and don’t make the bars micro) but when I exceed 600px the graph scales but the div wrapper around it doesn’t. So I get some cut of graph within the 600px div / x-axis is missing (image 2). Is there a way to scale the graph and the wrapper in Streamlit?


Hey @jpigla !

I noticed the same thing just yesterday :confused:, I probably need to resize the div after the chart axis labels has been displayed instead of at chart creation, when the label are not there yet. That or add an argument for manual padding.

I’ll try to fix this weekend and do a minor release. Do you mind creating an issue on GitHub - andfanilo/streamlit-echarts: A Streamlit component to render ECharts. with your sample code?

Have a nice day :balloon:
Fanilo

1 Like

Hello everyone!

Thanks to @Bright who has created st_echarts_events, streamlit 0.4.0 is out now :partying_face: and brings

:information_source: return values in ECharts events are now sent back to Streamlit

As simple as:

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

Demo app: https://share.streamlit.io/andfanilo/streamlit-echarts-events-demo/main
Demo code: GitHub - andfanilo/streamlit-echarts-events-demo
Announcement: https://twitter.com/andfanilo/status/1470353622374526977

:rocket: pip install -U streamlit-echarts

Don’t hesitate to tell me if there is any problem as I have not tested all the echarts events on all chart items :slight_smile:

Happy echarting with Streamlit :balloon:
Fanilo

4 Likes

Hi there ! first of all thanks for this wonderful lib.
I’m having a problem accessing my app on multiple devices.
Eg: this pie chart, on my monitor is perfect (24’’), on a 17’’ notebook it looks like this.
is it possible to freeze the legend so that it doesn’t overlay the graph?

thanks!!

Hi @felipejardimf

Saw your post but am currently in holidays, I’ll get back to you soonish!

Have a nice day,
Fanilo

1 Like

Sure, thank you for your attention :slight_smile:

My first option is same as yours, i prefer plotly and very nice to have your take on that.

@andfanilo hey, sorry for the inconvenience, but could you see about my question? :slight_smile:
thank you!

@andfanilo

If I have the days and data series in a python pandas dataframe, how may I pass the dataframe to the below code to get the E-Charts up and running.

A bit newbie to JS, please help me on this.

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"}],
}
st_echarts(
    options=option, height="400px",
)

My dataframe say is called ‘df’, with ‘days’ and ‘series’ as the column names. How may I generate the e-charts using the code in streamlit.

Thank You for your help!

@pitanjal (Doing this from memory, hope it works) You should be able to replace ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] by df["days"].values and [820, 932, 901, 934, 1290, 1330, 1320] by df["series"].values. You extract a column from your Dataframe as a Series and use .values to render it as a list :wink:

Have a nice day,
Fanilo

1 Like

Hey @felipejardimf

Sorry had not had a chance to look yet :confused: but it’s in my TODO list!

I’ll come back to you

@andfanilo Thank you so much for guiding me, yes now I get it.

I had one more question. I was going through some examples on E-Charts website. There is a JS script as follows.

option = {
  title: {
    text: 'Rainfall vs Evaporation',
    subtext: 'Fake Data'
  },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: ['Rainfall', 'Evaporation']
  },
  toolbox: {
    show: true,
    feature: {
      dataView: { show: true, readOnly: false },
      magicType: { show: true, type: ['line', 'bar'] },
      restore: { show: true },
      saveAsImage: { show: true }
    }
  },
  calculable: true,
  xAxis: [
    {
      type: 'category',
      // prettier-ignore
      data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    }
  ],
  yAxis: [
    {
      type: 'value'
    }
  ],
  series: [
    {
      name: 'Rainfall',
      type: 'bar',
      data: [
        2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
      ],
      markPoint: {
        data: [
          { type: 'max', name: 'Max' },
          { type: 'min', name: 'Min' }
        ]
      },
      markLine: {
        data: [{ type: 'average', name: 'Avg' }]
      }
    },
    {
      name: 'Evaporation',
      type: 'bar',
      data: [
        2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
      ],
      markPoint: {
        data: [
          { name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
          { name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
        ]
      },
      markLine: {
        data: [{ type: 'average', name: 'Avg' }]
      }
    }
  ]
};

How may I use this above code to generate the graph in my streamlit app? Is there a way?

Thanks a lot for your guidance!

I don’t describe the full process but the 10 second bit starting at 0:30 in that video that may help: Catch mouse events on ECharts plots in Streamlit | Introducing streamlit-echarts 0.4.0 - YouTube

Generally:

  • Put double quotes in the JSON keys in Python
  • All booleans should be uppercase
  • Add your df[col].values in place of data
  • If needed, you can write the JSON spec in an external file in your project, load it with json.loads (so the JSON to Python Dict is done by json.loads instead of you hardcoding the change) and then replace the data points option[“xAxis”][0][“data”] = df[col].values

Hope it helps :balloon:
Fanilo

1 Like

Hey!

I want to include a graph written in Javascript/TypeScript from the Apache E-Charts library. Is there a way to include these graphs in my streamlit app?

option = {
  title: {
    text: 'Rainfall vs Evaporation',
    subtext: 'Fake Data'
  },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: ['Rainfall', 'Evaporation']
  },
  toolbox: {
    show: true,
    feature: {
      dataView: { show: true, readOnly: false },
      magicType: { show: true, type: ['line', 'bar'] },
      restore: { show: true },
      saveAsImage: { show: true }
    }
  },
  calculable: true,
  xAxis: [
    {
      type: 'category',
      // prettier-ignore
      data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    }
  ],
  yAxis: [
    {
      type: 'value'
    }
  ],
  series: [
    {
      name: 'Rainfall',
      type: 'bar',
      data: [
        2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
      ],
      markPoint: {
        data: [
          { type: 'max', name: 'Max' },
          { type: 'min', name: 'Min' }
        ]
      },
      markLine: {
        data: [{ type: 'average', name: 'Avg' }]
      }
    },
    {
      name: 'Evaporation',
      type: 'bar',
      data: [
        2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
      ],
      markPoint: {
        data: [
          { name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
          { name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
        ]
      },
      markLine: {
        data: [{ type: 'average', name: 'Avg' }]
      }
    }
  ]
};

The above code is for JavaScript and the below for TypeScript to generate graphs.

option = {
  title: {
    text: 'Rainfall vs Evaporation',
    subtext: 'Fake Data'
  },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: ['Rainfall', 'Evaporation']
  },
  toolbox: {
    show: true,
    feature: {
      dataView: { show: true, readOnly: false },
      magicType: { show: true, type: ['line', 'bar'] },
      restore: { show: true },
      saveAsImage: { show: true }
    }
  },
  calculable: true,
  xAxis: [
    {
      type: 'category',
      // prettier-ignore
      data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    }
  ],
  yAxis: [
    {
      type: 'value'
    }
  ],
  series: [
    {
      name: 'Rainfall',
      type: 'bar',
      data: [
        2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
      ],
      markPoint: {
        data: [
          { type: 'max', name: 'Max' },
          { type: 'min', name: 'Min' }
        ]
      },
      markLine: {
        data: [{ type: 'average', name: 'Avg' }]
      }
    },
    {
      name: 'Evaporation',
      type: 'bar',
      data: [
        2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
      ],
      markPoint: {
        data: [
          { name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
          { name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
        ]
      },
      markLine: {
        data: [{ type: 'average', name: 'Avg' }]
      }
    }
  ]
};


Please may you guide me on how to include such graphs in my streamlit app, that has been written in JavaScript/Typescript.

Thanks!

The option is still JSON, there is no Javascript/Typescript code in there so you should be able to fit it in Python with some changes. You should be able to build a Python Dict that looks the same as this JSON for example

option = {'calculable': True,
 'legend': {'data': ['Rainfall', 'Evaporation']},
 'series': [{'data': [2.0,
                      4.9,
                      7.0,
                      23.2,
                      25.6,
                      76.7,
                      135.6,
                      162.2,
                      32.6,
                      20.0,
                      6.4,
                      3.3],
             'markLine': {'data': [{'name': 'Avg', 'type': 'average'}]},
             'markPoint': {'data': [{'name': 'Max', 'type': 'max'},
                                    {'name': 'Min', 'type': 'min'}]},
             'name': 'Rainfall',
             'type': 'bar'},
            {'data': [2.6,
                      5.9,
                      9.0,
                      26.4,
                      28.7,
                      70.7,
                      175.6,
                      182.2,
                      48.7,
                      18.8,
                      6.0,
                      2.3],
             'markLine': {'data': [{'name': 'Avg', 'type': 'average'}]},
             'markPoint': {'data': [{'name': 'Max',
                                     'value': 182.2,
                                     'xAxis': 7,
                                     'yAxis': 183},
                                    {'name': 'Min',
                                     'value': 2.3,
                                     'xAxis': 11,
                                     'yAxis': 3}]},
             'name': 'Evaporation',
             'type': 'bar'}],
 'title': {'subtext': 'Fake Data', 'text': 'Rainfall vs Evaporation'},
 'toolbox': {'feature': {'dataView': {'readOnly': False, 'show': True},
                         'magicType': {'show': True, 'type': ['line', 'bar']},
                         'restore': {'show': True},
                         'saveAsImage': {'show': True}},
             'show': True},
 'tooltip': {'trigger': 'axis'},
 'xAxis': [{'data': ['Jan',
                     'Feb',
                     'Mar',
                     'Apr',
                     'May',
                     'Jun',
                     'Jul',
                     'Aug',
                     'Sep',
                     'Oct',
                     'Nov',
                     'Dec'],
            'type': 'category'}],
 'yAxis': [{'type': 'value'}]}

st_echarts(option)

Try to see here how the JSON and this Python Dict are very similar :wink:

1 Like

Thank you so much for always guiding me @andfanilo

2 Likes

Hi @andfanilo thanks for this component. There is any way to implement the Gantt chart with option to drag and drop bars? Examples - Apache ECharts

I would like to implement this kind of chart in Streamlit, and get back the dataframe based on the changes done in the chart.