Python的可视化工具
python的数据可视化工具有很多,比如常见的matplotlib,但是讲到视觉效果的华丽,动态的交互,目前最漂亮的应该就是Echarts了。用Echarts可以做出很多漂亮的图形。Python里也有pyecharts,但是这种单一的图表页面做简单展示还可以,做一个完整的项目案例就比较麻烦了。
我对js几乎不懂,不过看了一下语法结构,还是很接近python和C++的,而js的数据传输,一般通过POST+ajax推送json数据完成(也许是我见到太少),这种语句比较常见,把语句做好了解析就可以用到单个需要数据驱动的Echarts上面。这是常见的思路。
Flask驱动Echarts的路线图
- 设计图表页面,引用echarts.js,设计图表框架
- 图表框架中嵌入接收数据的ajax
- Flask发送图表页面echarts.html
- Flask发送接送数据json
- 浏览器渲染图表页面echarts,运行含有ajax的js之后接收json数据
- json数据填充echarts,图表页面渲染完成
从这个路线图看,起始都是flask向浏览器发送数据,对于浏览器来说,只不过是两次"GET",并不是太难。
接下来,分布进行实施。
1.设计图表页面
在head中引入echarts.js
在body中留出一个容器Dom,这都是常见操作
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js -->
<script type="text/javascript" src="{{%20url_for('static',filename='js/echarts.min.js')%20}}"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:600px;"></div>
<!-- 定义echarts结构的JavaScript -->
</body>
</html>
接下来在body中设计JavaScript 定义echarts对象结构。
用item_name代表echarts的X轴名称,item_value代表名称对应的值
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
//建立ajax所需的json数据
var json_data=
{ item_name:[], item_value:[] };
//发送ajax数据请求
$(document).ready(function()
{
getData();
});
</script>
2.图表框架中嵌入接收数据的ajax
接下来,设计接收数据的ajax放到getDta()函数中。
ajax之后,是加载数据到图表中。
再补一个出错处理。
可以看到,ajax接收的是封装的json,也就是文本化的dictionary。这对后台来说,简直太方便了。
function getData()
{
$.ajax({
url:'/echart_json', //渲染的是/ehart_json下的json数据
data:{}, //接收数据存放的位置
type:'GET', //此处是从服务器获取数据,不涉及发送,因此是GET
async:false, //异步请求 同步请求将会锁住浏览器,用户其他操作必须等待请求完成才可以执行,默认false
dataType:'json',
success:function(data)
{ json_data=data;
// 指定图表的配置项和数据
var option =({
title: {text:'大灯材料类型'},
tooltip: {},
legend: { data:['材料'] },
//X轴是由json发送的字典中item_name获取的
xAxis: { data: json_data['item_name']},
yAxis: {},
//Y轴数据系列1的data是由json发送的字典中item_value获取的
series: [{name: '数量',
type: 'bar',
data: json_data['item_value']}]
});
myChart.hideLoading(); //隐藏加载动画
myChart.setOption(option); // 初次加载图表
},
//如获取数据失败,则提示
error:function(msg)
{ console.log(msg);
alert("数据加载失败!请检查数据链接是否正确");}
})
这部分函数设计完成之后,放到刚才的JavaScript中。这段函数是从网上抄的,但是看起来并不是很费力。
3.Flask发送图表页面
在视图代码中加入图表页面的路由代码:
from flask import Flask,Response,request
from flask import url_for
from flask import render_template
import json
app = Flask(__name__)
@app.route('/echarts')
def echarts():
return render_template('echarts.html',title='echarts')
4.Flask发送图表Json数据
在视图代码中加入发送json数据的路由代码:
def Response_headers(content):
resp = Response(content)
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp
@app.route('/echart_json')
def get_data():
item_name = ['LED', '卤素', '氙气']
item_value = ['266', '126', '15']
datas = {'item_name': item_name, 'item_value': item_value}
# 如果有中文的话,就需要ensure_ascii=False
content = json.dumps(datas, ensure_ascii=False)
resp = Response_headers(content)
return resp
5.浏览器渲染页面接收数据
6.Echarts格式调整
(1) 以下是柱状图的参数设置,参考博客:https://blog.csdn.net/qq_42816550/article/details/91604978
写的非常清楚,用心了。
版权声明:本文为CSDN博主「除了奋斗别无选择」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上
//定义图表option
var option = {
//标题,每个图表最多仅有一个标题控件,每个标题控件可设主副标题
title: {
//主标题文本,'\n'指定换行
text: '2013年广州降水量与蒸发量统计报表',
//主标题文本超链接
link: 'http://www.tqyb.com.cn/weatherLive/climateForecast/2014-01-26/157.html',
//副标题文本,'\n'指定换行
subtext: 'www.stepday.com',
//副标题文本超链接
sublink: 'http://www.stepday.com/myblog/?Echarts',
//水平安放位置,默认为左侧,可选为:'center' | 'left' | 'right' | {number}(x坐标,单位px)
x: 'left',
//垂直安放位置,默认为全图顶端,可选为:'top' | 'bottom' | 'center' | {number}(y坐标,单位px)
y: 'top'
},
//提示框,鼠标悬浮交互时的信息提示
tooltip: {
//触发类型,默认('item')数据触发,可选为:'item' | 'axis'
trigger: 'axis'
},
//图例,每个图表最多仅有一个图例
legend: {
//显示策略,可选为:true(显示) | false(隐藏),默认值为true
show: true,
//水平安放位置,默认为全图居中,可选为:'center' | 'left' | 'right' | {number}(x坐标,单位px)
x: 'center',
//垂直安放位置,默认为全图顶端,可选为:'top' | 'bottom' | 'center' | {number}(y坐标,单位px)
y: 'top',
//legend的data: 用于设置图例,data内的字符串数组需要与sereis数组内每一个series的name值对应
data: ['蒸发量','降水量']
},
//工具箱,每个图表最多仅有一个工具箱
toolbox: {
//显示策略,可选为:true(显示) | false(隐藏),默认值为false
show: true,
//启用功能,目前支持feature,工具箱自定义功能回调处理
feature: {
//辅助线标志
mark: {show: true},
//dataZoom,框选区域缩放,自动与存在的dataZoom控件同步,分别是启用,缩放后退
dataZoom: {
show: true,
title: {
dataZoom: '区域缩放',
dataZoomReset: '区域缩放后退'
}
},
//数据视图,打开数据视图,可设置更多属性,readOnly 默认数据视图为只读(即值为true),可指定readOnly为false打开编辑功能
dataView: {show: true, readOnly: true},
//magicType,动态类型切换,支持直角系下的折线图、柱状图、堆积、平铺转换
magicType: {show: true, type: ['line', 'bar']},
//restore,还原,复位原始图表
restore: {show: true},
//saveAsImage,保存图片(IE8-不支持),图片类型默认为'png'
saveAsImage: {show: true}
}
},
//是否启用拖拽重计算特性,默认关闭(即值为false)
calculable: true,
//直角坐标系中横轴数组,数组中每一项代表一条横轴坐标轴,仅有一条时可省略数值
//横轴通常为类目型,但条形图时则横轴为数值型,散点图时则横纵均为数值型
xAxis: [
{
//显示策略,可选为:true(显示) | false(隐藏),默认值为true
show: true,
//坐标轴类型,横轴默认为类目型'category'
type: 'category',
//类目型坐标轴文本标签数组,指定label内容。 数组项通常为文本,'\n'指定换行
data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']
}
],
//直角坐标系中纵轴数组,数组中每一项代表一条纵轴坐标轴,仅有一条时可省略数值
//纵轴通常为数值型,但条形图时则纵轴为类目型
yAxis: [
{
//显示策略,可选为:true(显示) | false(隐藏),默认值为true
show: true,
//坐标轴类型,纵轴默认为数值型'value'
type: 'value',
//分隔区域,默认不显示
splitArea: {show: true}
}
],
//sereis的数据: 用于设置图表数据之用。series是一个对象嵌套的结构;对象内包含对象
series: [
{
//系列名称,如果启用legend,该值将被legend.data索引相关
name: '蒸发量',
//图表类型,必要参数!如为空或不支持类型,则该系列数据不被显示。
type: 'bar',
//系列中的数据内容数组,折线图以及柱状图时数组长度等于所使用类目轴文本标签数组axis.data的长度,并且他们间是一一对应的。数组项通常为数值
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: '最大值'},
{type: 'min', name: '最小值'}
]
},
//系列中的数据标线内容
markLine: {
data: [
{type: 'average', name: '平均值'}
]
}
},
{
//系列名称,如果启用legend,该值将被legend.data索引相关
name: '降水量',
//图表类型,必要参数!如为空或不支持类型,则该系列数据不被显示。
type: 'bar',
//系列中的数据内容数组,折线图以及柱状图时数组长度等于所使用类目轴文本标签数组axis.data的长度,并且他们间是一一对应的。数组项通常为数值
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: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
//系列中的数据标线内容
markLine: {
data: [
{type: 'average', name: '平均值'}
]
}
}
]
};
//为echarts对象加载数据
myChart.setOption(option);
}
);
(2)还有一个比较重要的是formatter的设置
这是整个图形的tooltip的formatter,可以设置鼠标经过的提示文字
tooltip: {
trigger: 'item',
折线(区域)图、柱状(条形)图、K线图 : {a}(系列名称),{b}(类目值),{c}(数值), {d}(无)
散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)
地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)
饼图、仪表盘、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
formatter: "{a} <br/>{c} ({d}%)" //显示 “系列名称 系列名称 20 (50%)”之类的效果
}
还有series里label的famatter设置:
itemStyle: { normal:
{ label:
{formatter: "{c}\n{d}%",
show: true,
position: "inside",
textStyle: {fontWeight: "bolder", fontSize: "12",color: "#000000" } }
}
}
可以在饼图里显示数量下一行百分比的效果。
7.Echarts最终效果
以下是调整后的最终效果,该有的都有了
关键的是json数据在后台输入,利用pymysql查询数据库转json这个难度就非常小了。
所以,通过这种方式,打通数据库与可视化Echarts界面的连接,可以说一件非常有意义的事情。