ECharts是一个由百度开发的纯 Javascript 的图表库,pyecharts是某三位大佬将ECharts移植到Python项目中的产物,在Python网站中可以更轻松的接入图表,但是个人感觉pyecharts比ECharts还是局限很大的,pyecharts0.5.x版本就更为缩水了,由于项目之前用的是pyecharts0.5.11版本,图表比较少,不足以解决问题,甚至自己用js实现了两个图表来使用,美观度比ECharts还是逊色不少,如果将项目迁移到新版pyecharts v1.0.0则更为麻烦,就直接在原来的项目中引入echarts库来混合使用,pyecharts v1.0.0虽然完善了不少问题,但是加入了新的配置规则,学习起来增加了不少负担,灵活度也没有echarts好,个人建议如果项目中使用的图表不是很复杂,数据静态的可以使用pyecharts,复杂点的还是尽量使用echarts比较方便,下面开始进入主题:

1. 安装pyecharts:

pip install pyecharts==0.5.11  #0.5.x的旧版,我目前使用的这个,要用pyecharts的话建议安装下面的最新版

pip install pyecharts     #安装最新版

pyecharts使用图表可以直接在视图代码里面构建图表,Django会将其渲染到前端模板页面中:

# 主体图-1
def visualPage(request):
template = loader.get_template('visualModule/visualPage.html') #载入模板文件 parseArgData() data3D1,weights3D1,bar = drawBar() #得到图表数据
context = dict( #context添加在模板中要渲染的数据
myechart = bar.render_embed(),  #图表数据
host = DEFAULT_HOST,
script_list = bar.get_js_dependencies(),  #由pyecharts引入需要用到的js代码文件
guestSetArgs=startArgsSet,
warningdata=argList,
data3D=data3D1,
weights3D=weights3D1,
)
return HttpResponse(template.render(context, request))#

构建图表函数,这里只粘贴了图表的接口代码,数据处理和逻辑代码略去:

def drawBar(): #绘制
x_axis = ['','','','','','','','','','','',''] #X轴
y_axis = [0,1,2,3,4,5,6,7,8,9,10,11]     
data = [
#闭源5个
dict(
name = "",
value=[so[0], sor[0], projects[0][0][""]],
itemStyle=dict(color=getColorstr2(0,weights[0]))
), dict(
name="",
value=[so[4], sor4[2], projects[4][2][""]],
itemStyle=dict(color=getColorstr2(4,weights[18]))
), ...
]
bar3d = Bar3D("", width=1000, height=500)
bar3d.add("",x_axis,y_axis, data,
is_visualmap=False,
is_xaxis_show=True,
is_yaxis_show=False,
is_splitline_show=False,
xaxis3d_name =' ',
yaxis3d_name =' ', #is_label_show =True,
mark_point_symbol='circle',
is_more_utils=True,
mark_point=['max','min'],
mark_line=['average'], zaxis3d_name ='评分',
xaxis3d_interval =0,
grid3d_width=150, grid3d_depth=100,
grid3d_shading='realistic',
is_grid3d_ratate = True,
grid3d_rotate_speed=180,
tooltip_formatter=formatter) bar3d.on(MOUSE_CLICK, on_click)
return data,weights,bar3d
<!--  模板代码-->
<div> {{ myechart|safe }}
<br>
{{radarChart|safe}} </div>

这样就可以在前端显示柱状图图表了

另外项目中还使用了一个折线图也是同样做法:

其他图表也是类似添加,可以参考pyecharts官网教程:

https://pyecharts.org/#/

2. 接下来在项目中再引入echarts来使用,和pyecharts混合使用互不影响

安装可参考echarts官网:

https://www.echartsjs.com/zh/

去https://github.com/apache/incubator-echarts下载echarts源码包,解压出来的文件夹里的 dist 目录里可以找到最新版本的 echarts 库,直接在前端页面中引入即可使用echarts图表,

 {% for jsfile_name in script_list %}
<script src="{{ host }}/{{ jsfile_name }}.js"></script>
{% endfor %} <script src="{% static 'js/dist/echarts.min.js' %}"></script>
<script src="{% static 'js/dist/echarts-gl.js' %}"></script>
 <div id="container3" style="height: 800px"></div>

       <script type="text/javascript">
//echarts柱状图
var dom3 = document.getElementById("container3");
var myChart3 = echarts.init(dom3);
var app = {};
option = null; var hours = [];
var days = []; $.get("{% static 'json/eachBar3dData.json' %}",function (json_data) {
var jdata=[];
$(json_data.items).each(function(i,ite){  
jdata.push(ite)
})
rectSize=Math.sqrt(json_data.length);
for(var i=0;i<rectSize;i++)
{
hours.push('');
days.push('');
}
option = {
title: {
text: '所有代码子模块代码数量3D柱状图',
subtext: '可显示代码数量,缺陷情况',
left: 'leafDepth'
},
tooltip: {
formatter:function(params)
{
var errors=0;
for(var i =0;i< json_data.length;i++)
{
if (json_data[i][3]==params.name)
{
errors=json_data[i][4];
break;
}
}
return "<div >"+"文件路径:"+params.name+'<br>'+
"代码行数:"+params.value[2]+'<br>'+
"缺陷数量:"+errors+
"</div>";
},
},
visualMap: {
max: 4000,
inRange: {
color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
}
},
xAxis3D: {
type: 'category',
data: hours,
name: ''
},
yAxis3D: {
type: 'category',
data: days,
name:''
},
zAxis3D: {
type: 'value',
name:'代码数量'
},
grid3D: {
boxWidth: 200,
boxDepth: 180,
viewControl: {
// projection: 'orthographic'
},
light: {
main: {
intensity: 1.2,
shadow: true
},
ambient: {
intensity: 0.3
}
}
},
/* dataset: {
dimensions: [
'Income',
'Life Expectancy',
'Population',
'Country',
{name: 'Year', type: 'ordinal'}
],
source: json_data
},
*/
series: [{
type: 'bar3D',
data: json_data.map(function (item) {
return {
name:item[3],
value: [item[1], item[0], item[2]],
}
}),
shading: 'lambert', label: {
textStyle: {
fontSize: 16,
borderWidth: 0
}
}, emphasis: {
label: {
textStyle: {
fontSize: 20,
color: '#900'
}
},
itemStyle: {
color: '#900'
}
}
}]
};
myChart3.setOption(option, true);
});
if (option && typeof option === "object") {
myChart3.setOption(option, true);
}
</script> </div>

显示效果:

另外项目中还用到树形图表用来表示文件目录结构:

可钻入的矩形树图:

由于pyecharts0.5.x中不存在这个图表,pyecharts v1.0.0和echarts中没有添加还是我没有认真看也没有发现这个,就自己实现了和这个类似的钻入树形图表:

同时为了练手也自己实现了一个条形图表:

图形条数和形状是根据数据变化来做适应的,但是美观度比echarts还是逊色不少

3 . echarts事件交互的使用

项目中使用到一个雷达图,需要鼠标点击便签进入便签的子图,也是一个类似的钻入图形,逻辑代码部分较多,省略了getOption( argName)函数中的部分逻辑代码:

 <div id="container" style="height: 800px"></div>

       <script type="text/javascript">
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};
var weight=1000; //权重的倍数
var weight1=800;
function getOption( argName){
var ardData=[]; if(argName=="闭源特性"){ //判断点击文字
var weightBuf= [{{weights3D.0}},{{weights3D.1}},{{weights3D.2}},{{weights3D.3}},{{weights3D.4}},
]; var weightBuf1=[];
weightBuf.forEach(myFunction);
function myFunction(value, index, array) {
weightBuf1.push(value*weight1);
}
ardData=[
{
value : [{{data3D.0.value.2}},{{data3D.1.value.2}},{{data3D.2.value.2}},{{data3D.3.value.2}},{{data3D.4.value.2}},
],
name : '评分'
},
{
value : weightBuf1,
name : '权重'
}
];
option = null;
option = {
title: {
text: '雷达图',
subtext: '点击文字要素返回顶层属性雷达图',
},
tooltip: {
formatter:function(params)
{
namelist=['正确性', '可靠性', '安全性', '可理解性','代码熵']
var eachli=params.value;
if (params.name=='权重')
eachli=weightBuf;
return "<div >"+params.name+'<br>'+
namelist[0]+':'+eachli[0]+'<br>'+
namelist[1]+':'+eachli[1]+'<br>'+
namelist[2]+':'+eachli[2]+'<br>'+
namelist[3]+':'+eachli[3]+'<br>'+
namelist[4]+':'+eachli[4]+
"</div>";
},
},
legend: {
data: ['评分(scole)', '权重(weight)']
},
radar: {
// shape: 'circle',
name: {
textStyle: {
color: '#000',
backgroundColor: '#dee',
borderRadius: 3,
padding: [3, 5]
}
},
indicator: [
{ name: '正确性', max: 100},
{ name: '可靠性', max: 100},
{ name: '安全性', max: 100},
{ name: '可理解性', max: 100},
{ name: '代码熵', max: 100},
],
triggerEvent:true
}, series: [{
name: '评分 vs 权重',
type: 'radar',
// areaStyle: {normal: {}},
data : ardData
}]
};;
}
return option;
}
option=getOption("root");
if (option && typeof option === "object") {
myChart.setOption(option, true); myChart.on('click', function (params) {
console.log(params);
// alert(params.name);
myChart.setOption(getOption(params.name), true);
}); }
</script>

主要是用

 myChart.on('click', function (params) {
console.log(params);
// alert(params.name);
myChart.setOption(getOption(params.name), true);
});
来监听鼠标点击标签事件,然后通过getOption来动态构建option显示,就达到了钻入效果

点击之后的钻入效果

4. 自定义tooltip标签

在tooltip中定义formatter,params参数为当前活动的元素数据

tooltip: {
formatter:function(params)
{
var errors=0;
for(var i =0;i< json_data.length;i++)
{
if (json_data[i][3]==params.name)
{
errors=json_data[i][4];
break;
}
}
return "<div >"+"文件路径:"+params.name+'<br>'+
"代码行数:"+params.value[2]+'<br>'+
"缺陷数量:"+errors+
"</div>";
},
},

效果:

提示框浮层内容格式器,支持字符串模板和回调函数两种形式。

1, 字符串模板

模板变量有 {a}{b}{c}{d}{e},分别表示系列名,数据名,数据值等。 在 trigger 为 'axis' 的时候,会有多个系列的数据,此时可以通过 {a0}{a1}{a2} 这种后面加索引的方式表示系列的索引。 不同图表类型下的 {a}{b}{c}{d} 含义不一样。 其中变量{a}{b}{c}{d}在不同图表类型下代表数据含义为:

  • 折线(区域)图、柱状(条形)图、K线图 : {a}(系列名称),{b}(类目值),{c}(数值), {d}(无)

  • 散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)

  • 地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)

  • 饼图、仪表盘、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)

更多其它图表模板变量的含义可以见相应的图表的 label.formatter 配置项。

示例:

formatter: '{b0}: {c0}<br />{b1}: {c1}'

2, 回调函数

回调函数格式:

(params: Object|Array, ticket: string, callback: (ticket: string, html: string)) => string

第一个参数 params 是 formatter 需要的数据集。格式如下:

{
componentType: 'series',
// 系列类型
seriesType: string,
// 系列在传入的 option.series 中的 index
seriesIndex: number,
// 系列名称
seriesName: string,
// 数据名,类目名
name: string,
// 数据在传入的 data 数组中的 index
dataIndex: number,
// 传入的原始数据项
data: Object,
// 传入的数据值。在多数系列下它和 data 相同。在一些系列下是 data 中的分量(如 map、radar 中)
value: number|Array|Object,
// 坐标轴 encode 映射信息,
// key 为坐标轴(如 'x' 'y' 'radius' 'angle' 等)
// value 必然为数组,不会为 null/undefied,表示 dimension index 。
// 其内容如:
// {
// x: [2] // dimension index 为 2 的数据映射到 x 轴
// y: [0] // dimension index 为 0 的数据映射到 y 轴
// }
encode: Object,
// 维度名列表
dimensionNames: Array<String>,
// 数据的维度 index,如 0 或 1 或 2 ...
// 仅在雷达图中使用。
dimensionIndex: number,
// 数据图形的颜色
color: string, // 饼图的百分比
percent: number, }
我这里使用的回调函数,定义雷达图更方便一点
其他可参考官方文档教程:
https://www.echartsjs.com/zh/option.html#title

pyecharts和echarts的混合使用的更多相关文章

  1. 小白学 Python 数据分析(20):pyecharts 概述

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  2. python模块统计

    .处理日期和时间 datetime/time/pytz/dateutil/calendar 注:calendar有很广泛的方法用来处理年历和月历,例如打印某月的月历 .处理字符串 re .处理字符集编 ...

  3. django使用pyecharts(1)----django加入echarts

    Django 中使用 pyecharts.一.普通django加入echarts Django 模板渲染 Step 0: 新建一个 Django 项目 $ django-admin startproj ...

  4. Python爬取南京市往年天气预报,使用pyecharts进行分析

    上一次分享了使用matplotlib对爬取的豆瓣书籍排行榜进行分析,但是发现python本身自带的这个绘图分析库还是有一些局限,绘图不够美观等,在网上搜索了一波,发现现在有很多的支持python的绘图 ...

  5. Python:数据可视化pyecharts的使用

    什么是pyecharts? pyecharts 是一个用于生成 Echarts 图表的类库. echarts 是百度开源的一个数据可视化 JS 库,主要用于数据可视化.pyecharts 是一个用于生 ...

  6. Python中的可视化神器:pyecharts

    pyecharts是一款将python与echarts结合的强大的数据可视化工具,本文将为你阐述pyecharts的使用细则 前言 我们都知道python上的一款可视化工具matplotlib,而前些 ...

  7. 数据可视化之pyecharts

    Echarts 是百度开源的一个数据可视化 JS 库,主要用于数据可视化.pyecharts 是一个用于生成 Echarts 图表的类库.实际上就是 Echarts 与 Python 的对接. 安装 ...

  8. python可视化pyecharts

    python可视化pyecharts 简单介绍 pyecharts 是一个用于生成 Echarts 图表的类库.Echarts 是百度开源的一个数据可视化 JS 库.用 Echarts 生成的图可视化 ...

  9. ECharts教程

    ECharts 特性 兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等) 底层依赖轻量级的矢量图形库 ZRender 丰富的可视化类型 常规的折线图.柱状图 ...

随机推荐

  1. 利用 Docker Compose 搭建 SpringBoot 运行环境(超详细步骤和分析)

    0.前言 相信点进来看这篇文章的同学们已经对 Docker Dompose 有一定的了解了,下面,我们拿最简单的例子来介绍如何使用 Docker Compose 来管理项目. 本文例子: 一个应用服务 ...

  2. Unrecognized header format %

    <VirtualHost *:*> RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME} </ ...

  3. 【转】java中使用WebSocket

    传统的请求,都是从客服端到服务端,表现在web应用上就是,消息都只能由浏览器发起请求,调用客户端的方法. webSocket可以从服务器端推送消息给浏览器. 使用场景: 当客户端发起缴费请求时,由服务 ...

  4. Druid-代码段-1-2

    所属文章:池化技术(一)Druid是如何管理数据库连接的? 本代码段对应流程1.1,责任链的执行: //DruidDataSource类里的方法:获取连接 public DruidPooledConn ...

  5. acwing 517. 信息传递

    地址 https://www.acwing.com/problem/content/description/519/ 有 n 个同学(编号为 1 到 n)正在玩一个信息传递的游戏. 在游戏里每人都有一 ...

  6. [C5W2] Sequence Models - Natural Language Processing and Word Embeddings

    第二周 自然语言处理与词嵌入(Natural Language Processing and Word Embeddings) 词汇表征(Word Representation) 上周我们学习了 RN ...

  7. 让你的网页"抖起来"?!?

    细心的小伙伴可能发现我的左下角有一个抖起来的小按钮,然后页面就开始皮了起来,哈哈好快乐啊 没有利用js,单独的使用了css3的动画就实现了这个效果 css设置 @keyframes shake-it{ ...

  8. 错题shell

    1.判断/root/class21/inittab.txt文件是否大于100行,如果大于,则显示”inittab is a big file.”否者显示”inittab is a small file ...

  9. 【2019.8.20 NOIP模拟赛 T3】小X的图(history)(可持久化并查集)

    可持久化并查集 显然是可持久化并查集裸题吧... 就是题面长得有点恶心,被闪指导狂喷. 对于\(K\)操作,直接\(O(1)\)赋值修改. 对于\(R\)操作,并查集上直接连边. 对于\(T\)操作, ...

  10. Luogu P5298 [PKUWC2018]Minimax

    好劲的题目啊,根本没往线段树合并方面去想啊 首先每种权值都有可能出现,因此我们先排个序然后一个一个求概率 由于此时数的值域变成\([1,m]\)(离散以后),我们可以设一个DP:\(f_{x,i}\) ...