Charts are a great way to communicate information visually. When used in user interfaces, they can help users understand data more easily and make better decisions. In this article, we will show you how to easily add charts to your python application using echarts.
Pyecharts is a Python library that allows you to create various types of charts and graphs without using javascript. It is a wrapper around the beautiful echarts library. It is easy to use and has a wide range of features. It is also open source and free to use. In this article, we will show you how to easily add charts to your python application using the pyecharts.
Install the pyecharts library or add it to your dependencies.
pip install pyecharts
Pyecharts is a library for configuring echarts options in python. For convenience, we will create a chart module where we will define standard charts that can be reused across the application.
charts/echarts.py
from pyecharts.charts import Bar, Line
from pyecharts.options import (
AreaStyleOpts,
AxisLineOpts,
AxisOpts,
AxisTickOpts,
InitOpts,
LabelOpts,
LegendOpts,
LineStyleOpts,
TextStyleOpts,
TitleOpts,
)
class Colors:
default = "#818cf8"
yellow = "#ffe5cb"
green = "#d3fce7"
TITLE_TEXT_STYLE_OPTIONS = TextStyleOpts(
color="#4b5562", font_size=16, font_weight="600"
)
TITLE_OPTS = {
"pos_top": "0px",
"pos_left": "2px",
"item_gap": 10,
"title_textstyle_opts": TITLE_TEXT_STYLE_OPTIONS,
}
AXIS_LINE_OPTS = AxisLineOpts(
linestyle_opts=LineStyleOpts(color="#9ca3af")
)
def line_chart(data: dict, color = None):
"""Line chart"""
color = color or Colors.default
# create chart instance
line = Line(init_opts=InitOpts(width="105%", height="300px"))
# add y,x axis data
line.add_xaxis(data["x"])
line.add_yaxis(
"",
data["y"],
is_smooth=False,
areastyle_opts=AreaStyleOpts(opacity=0.1, color=color),
label_opts=LabelOpts(is_show=False),
)
# add chart options
line.set_colors([color])
line.set_global_opts(
title_opts=TitleOpts(title=data["chart_title"], **TITLE_OPTS),
legend_opts=LegendOpts(is_show=False),
yaxis_opts=AxisOpts(
position="bottom",
name_location="end",
axisline_opts=AXIS_LINE_OPTS,
axistick_opts=AxisTickOpts(is_show=False),
),
xaxis_opts=AxisOpts(
axisline_opts=AXIS_LINE_OPTS, axistick_opts=AxisTickOpts(is_show=False)
),
)
# finally prepare chart options for rendering.
line._prepare_render()
return line
Notes
TitleOpts, InitOpts
- these are classes for defining configuration variables for the charts. For a full list of the options in echarts see this page.def line_chart(..)
- this method expects data
and color
as parameters. The color must be a hex string, the data should be a dictionary with values for x & y axis and a chart title. We will see an example in the view below.line = Line(init_opts=InitOpts(width="105%...)
- this line declares an instance of the Line
chart class with some initial options.line._prepare_render()
- finally we prepare the chart for rendering. This method formats the chart options and theme into JSON for rendering on the frontend.charts/views.py
from django.shortcuts import render
from charts.echarts import line_chart, Colors
def dashboard_view(request):
total_page_views = {
"x":["mon", "tue", "wed", "thur", "fri", "sat","sun"],
"y":[8,20,15,20,50,30, 35],
"chart_title": "Total Page Views",
}
unique_visitors = {
"x":["mon", "tue", "wed", "thur", "fri", "sat","sun"],
"y":[3,4,10,12,30,20,33],
"chart_title": "Unique Visitors",
}
signups = {
"x":["mon", "tue", "wed", "thur", "fri", "sat","sun"],
"y":[3,4,10,12,30,20,33],
"chart_title": "Signups",
}
charts = [
line_chart(total_page_views),
line_chart(unique_visitors, Colors.yellow),
line_chart(signups, Colors.green)
]
context = {
"charts": charts
}
return render(request, "dashboard.html", context)
Notes
def dashboard_view
- in this view, we create 3 line charts for our dashboard. Notice that we used custom colors for two of the charts.django_project/urls.py
urlpatterns = [
...
path("", dashboard_view, name='stats')
]
charts/dashboard.html(continued)
<html id="id-html" lang="{{ language_code }}" >
<head>
<title> Dashboard</title>
<meta charset="UTF-8">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-slate-100">
<div class="w-full max-w-5xl mx-auto flex flex-col space-y-5 p-4">
<div class="flex px-4 py-2 justify-between mt-10">
<span class="text-gray-600 font-semibold">📊 analytics.io</span>
<div class="bg-white rounded shadow p-2 text-sm text-gray-600 flex items-center font-semibold mr-2 cursor-pointer">Last Week
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
<div class="w-full grid grid-cols-2 gap-6">
{# loop through the list of charts and add placeholder divs to grid #}
{% for c in charts %}
<div class="bg-white shadow rounded-lg p-4 {% if forloop.counter0 == 0 %}col-span-2 {% endif %}">
<div id="{{ c.chart_id }}" class="chart-container" style="width:{{ c.width }}; height:{{ c.height }};">
</div>
</div>
{% endfor %}
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.3/echarts.min.js" integrity="sha512-2L0h0GhoIHQEjti/1KwfjcbyaTHy+hPPhE1o5wTCmviYcPO/TD9oZvUxFQtWvBkCSTIpt+fjsx1CCx6ekb51gw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
// todo below
</script>
</body>
</html>
Notes
<script src="https://cdn.tailwindcss.com"></script>
- we are using tailwindcss for styling. In production, make sure you minify your files. You can see our tutorial on using Django and tailwind if you need help with setting this up for your project.{% for c in charts %}
.. - here we loop through the list of charts and add them to a grid. {% if forloop.counter0 == 0 %}col-span-2 {% endif %}
- we added a bit of custom styling here to ensure that the first chart spans two columns.Almost there, let's add some javascript for rendering the charts.
charts/dashboard.html(continued)
...
<script>
document.addEventListener("DOMContentLoaded", function(){
{% for c in charts %}
var chart_{{ c.chart_id }} = echarts.init(
document.getElementById('{{ c.chart_id }}'),
'{{ c.theme }}',
{ renderer: '{{ c.renderer }}'}
);
{% for js in c.js_functions.items %}
{{ js|safe }}
{% endfor %}
var option_{{ c.chart_id }} = {{ c.json_contents|safe }};
chart_{{ c.chart_id }}.setOption(option_{{ c.chart_id }});
{% if c.width|slice:"-1:" == '%' %}
window.addEventListener('resize', function(){
chart_{{ c.chart_id }}.resize();
})
{% endif %}
{% endfor %}
})
</script>
Notes
Let's walk through it together.
{% for c in charts %}
- we loop through the charts
context variablevar chart_{{ c.chart_id }} = echarts.init(..)
- select each chart placeholder and initialize the chart.var option_{{ c.chart_id }} = {{ c.json_contents|safe }};
- this renders the chart options and sets them on the chart{% if c.width|slice:"-1:" == '%' %}
- for charts where we have set the width type as a percentage, we need to call the resize method to ensure that the chart fills up the right amount of space.The pyecharts library provides a clean python interface for configuring chart options from your python code. You can now easily add charts to display revenue data that your SaaS business is generating or the number of new users that are signing up for your SaaS service. In future articles, we will show you how to make the charts more interactive with HTMX.
A good starting point for using the python library is to have a look at the available configuration options in the core echarts javascript library docs and then use the equivalent in your python code.
If you want to build a SaaS product quickly and efficiently, without wasting time on core features such as Payments, Authentication, CRM, Teams, and more, check out the Vanty Starter Kit.
Related Articles
All ArticlesSuccess
Error
Warning
Info