Echarts基础:用python读取excel数据的网页可视化

最近在imooc上搜索数据分析,学习了一个python工程师体验营,主要内容是:

python基础 + python读取excel数据 + Echarts图表可视化

记录一下课程内容,巩固记忆(完整代码与结果在最下方)。

python运行后,在浏览器里输入 http://127.0.0.1:8080 + 你在python文件中定义的url

如本文示例:http://127.0.0.1:8080/chart 即可在网页中看到我们创建的图表

Echarts简介:

Apache ECharts是一个基于 JavaScript 的开源可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。

Echarts拥有丰富的功能,可以通过模板实现各种数据图表可视化,并且官网有许多示例,可以直接复制代码进行修改,实现自己的需要。

官网示例:

点击一个图,左边可以直接查看代码。

引用Echarts

进入Echarts官网Apache ECharts下载解压后,找到echarts.min文件,复制到所需项目的文件夹中,为它单独创立一个文件夹,再创建html的文件夹和.py文件。

使用Echarts读取数据

需要的框架:web.py和xlrd

在python中安装web.py和xlrd模块

import web
import xlrd

(一)web.py

web.py 是一个开源的轻量级Python web框架,无论用于什么用途都是没有限制的,而且相当的小巧,属于轻量级的web框架。

web.py的完整示例代码:

import web

urls = (
    '/(.*)', 'hello'
)
app = web.application(urls, globals())

class hello:
    def GET(self, name):
        if not name:
            name = 'World'
        return 'Hello, ' + name + '!'

if __name__ == "__main__":
    app.run()

第一部分 URL映射

我们需要告诉web.py如何组织url,比如:

# 路由配置
urls = (
    '/chart', 'chart'
)

元组格式为:('路径','处理类')

( '/' )是一个匹配url的正则表达式,有三种类型:

1. URL完全匹配

'/chart','Chart',由Chart类处理 http://127.0.0.1:8080/chart

2. URL模糊匹配

'/chart/\d+','Chart',由Chart类处理 http://127.0.0.1:8080/chart/1,chart/后接一个数字的url

3. URL带组匹配

'/chart/(\d+)','Chart',由Chart类处理 http://127.0.0.1:8080/chart/1,chart/后接数字的url,带组匹配与模糊匹配的区别是在正则表达式外部添加一个括号,即表达匹配一组。

带组匹配会匹配chart后的参数,模糊匹配则不会

第二部分 匹配模板

新建一个目录(命名为templates),在该目录下新建一个以html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
</html>

在顶部加上def with表示模板将从这后面取值(实例中name为sales_data)

$def with(name)

回到我们的.py文件,在url配置后加上代码:

app = web.application(urls, globals())
render = web.template.render('templates/')

application基本来说就是创建一个应用urls参数指明了网站url与应用执行的函数间的一个映射。

render则是告诉web.py到模板目录中去查找模板,最后在类里写return render.模板( ),如:

return render.chart(sales_data=sales_data, source_data=source_data,
                            source_title=source_all_title,
                            source_stat_data=source_stat_data,
                            clue_data=clue_data,
                            clue_title=clue_title)

最后再完成class中的GET方法用来处理相对应的url的GET请求。

class chart:
    def GET(self):

我的web.py部分代码(此处还没有加入读取数据的代码,是无法直接运行的):

import web
import xlrd

# 路由配置
urls = (
    '/chart', 'chart'
)
app = web.application(urls, globals())
render = web.template.render('templates/')


class chart:
    def GET(self):

        return render.chart(sales_data=sales_data, source_data=source_data,
                            source_title=source_all_title,
                            source_stat_data=source_stat_data,
                            clue_data=clue_data,
                            clue_title=clue_title)


if __name__ == '__main__':
    app.run()

(二)xlrd

xlrd是Python语言中,读取Excel的扩展工具。

1. 打开Excel文件读取数据

data = xlrd.open_workbook('excelFile.xls') 

2. 使用技巧

获取一个工作表

table = data.sheets()[0] #通过索引顺序获取

table = data.sheet_by_index(0) #通过索引顺序获取

table = data.sheet_by_name(u'Sheet1')#通过名称获取

获取整行和整列的值(数组)

table.row_values(i) 

table.col_values(i)

获取行数和列数

nrows = table.nrows

ncols = table.ncols

循环行列表数据

for i in range(nrows ):

print table.row_values(i)

组成最终导入模板的数据

使用Echarts时常用到name:value类型的字典,可直接读取某行或某列数据

# 读取excel数据
work_book = xlrd.open_workbook('data.xls')

# sheet 1
work_sheet_1 = work_book.sheet_by_index(0)
sales_data = {
     'category': work_sheet_1.row_values(0),
     'data': work_sheet_1.row_values(1)
}

 在html模板中将category作为y轴,data作为x轴

    xAxis:{
        type:'category',
        data:sales_data['category']
    },
    yAxis:{},
    series:[
        {
            'name':'销售额',
            type:'bar',
            data:sales_data['data'],

在饼状图中常用for循环结合append读取数据,构成我们最终导入到模板类的字典,如:

 分别读取第四行的标题和第五行的数据,将标题与数据对应存放到source_data里

        # sheet 2
        work_sheet_2 = work_book.sheet_by_index(1)
        source_data = []
        source_legend = []
        source_title = work_sheet_2.row_values(3)
        source_value = work_sheet_2.row_values(4)
        for idx in range(len(source_title)):
            tmp_data = {
                'name': source_title[idx],
                'value': source_value[idx]
            }
            source_data.append(tmp_data)

Echarts基本用法

1. 在<body></body>内引入echarts文件(charts文件放在static文件夹里)

<script src="static/echarts.min.js"></script>

2. 定义div容器存放图表

<body>
    <!-- 实例中 id 为 main 的 div 用于包含 ECharts 绘制的图表 -->
    <div id="main" style="width: 600px;height:400px;"></div>
</body>

在本文实例中,用了一些模板,一共定义了三幅图,下文介绍的是第一幅图sales_wrap:

<div class="container-fluid">
<div class="row">
    <div class="col-lg-12" id="sales_wrap" style="min-height: 400px;">

    </div>
    <div class="col-lg-6" id="source_wrap" style="min-height: 400px;">

    </div>
    <div class="col-lg-6" id="order_wrap" style="min-height: 400px;">

    </div>
</div>
</div>

3.设置配置信息(javascript部分)

基本格式

ECharts 库使用 json 格式来配置:

echarts.init(document.getElementById('main')).setOption(option);

使用var声明变量,此处option_1是第一幅图,其他入title等属性在下文进行介绍。

var option_1 = {
    title:{
    },
    xAxis:{
    },
    yAxis:{},
    series:[
    ],
    tooltip:{
    },
    toolbox:{
    }
};
chart_1.setOption(option_1);

补充第一幅图的数据源:

var sales_data = $:sales_data;

在html文件最上方加入声明:

$def with(sales_data)

接下来设置横纵坐标轴、工具栏等属性,即可画好第一幅图。

标题

    title:{
        text:'71公司月销售额',
        subtext:'销售额(单位:万)'
    },

X轴

可以直接写x轴代表的信息如:

xAxis: {
    data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
}

也可以连接我们导入的数据:取category这个列表的值作为横坐标

    xAxis:{
        type:'category',
        data:sales_data['category']
    },

Y轴

yAxis: {}

系列列表

    series:[
        {
            'name':'销售额',
            type:'bar',
            data:sales_data['data'],
            markPoint:{
                data:[
                    {type:"max",name:"最大值"},
                    {type:"min",name:"最小值"}
                ]
            },
            markLine:{
                data:[
                    {type:'average',name:'平均值'}
                ]
            }
        }
    ],

提示信息

    tooltip:{
        trigger:'axis'
    },

将鼠标放到坐标轴上会有详细数字信息显示

 工具栏

    toolbox:{
        show:true,
        feature:{
            dataView:{},
            magicType:{type:['line','bar']},
            restore:{},
            saveAsImage:{}
        }

show:true代表工具箱显示,图表右上角会出现工具箱选项,但要在feature中写了才会出现。

feature是一些功能属性,其中:

dataView是具体数值显示,点击后:

 magicType是图表类型转换,这里定义了我们的图表可以转换为条形图bar或者折线图line:

,点击Line Chart

再点击Bar Chart可回到原图,或者直接点击Restore还原

最后一个如名字一般,是保存图片 ,点击后即可下载图片

 到这里第一幅图已经完成啦。

最终结果展示与代码

我一共画了三幅图,格式参照第一幅图即可。

 

 python代码:

import web
import xlrd

# 路由配置
urls = (
    '/chart', 'chart'
)
app = web.application(urls, globals())
render = web.template.render('templates/')


class chart:
    def GET(self):

        # 读取excel数据
        work_book = xlrd.open_workbook('data.xls')

        # sheet 1
        work_sheet_1 = work_book.sheet_by_index(0)
        sales_data = {
            'category': work_sheet_1.row_values(0),
            'data': work_sheet_1.row_values(1)
        }
        print(sales_data)
        # sheet 2
        work_sheet_2 = work_book.sheet_by_index(1)
        source_data = []
        source_legend = []
        source_title = work_sheet_2.row_values(3)
        source_value = work_sheet_2.row_values(4)
        for idx in range(len(source_title)):
            tmp_data = {
                'name': source_title[idx],
                'value': source_value[idx]
            }
            source_data.append(tmp_data)

        source_stat_data = []
        source_stat_title = work_sheet_2.row_values(0, 0, 3)
        source_stat_value = work_sheet_2.row_values(1, 0, 3)
        for idx in range(len(source_stat_title)):
            tmp_stat_data = {
                'name': source_stat_title[idx],
                'value': source_stat_value[idx]
            }
            source_stat_data.append(tmp_stat_data)

        # 两个list进行合并
        source_all_title = source_stat_title + source_title

        # sheet 3
        work_sheet_3 = work_book.sheet_by_index(2)
        clue_data = []
        clue_title = work_sheet_3.row_values(0)
        clue_value = work_sheet_3.row_values(1)
        for idx in range(len(clue_title)):
            tmp_data = {
                'name': clue_title[idx],
                'value': clue_value[idx]
            }
            clue_data.append(tmp_data)

        return render.chart(sales_data=sales_data, source_data=source_data,
                            source_title=source_all_title,
                            source_stat_data=source_stat_data,
                            clue_data=clue_data,
                            clue_title=clue_title)


if __name__ == '__main__':
    app.run()



 html代码:

$def with(sales_data,source_data,source_title,source_stat_data,clue_data,clue_title)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>画图</title>
    <!-- Bootstrap -->
    <link href="static/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container-fluid">
<div class="row">
    <div class="col-lg-12" id="sales_wrap" style="min-height: 400px;">

    </div>
    <div class="col-lg-6" id="source_wrap" style="min-height: 400px;">

    </div>
    <div class="col-lg-6" id="order_wrap" style="min-height: 400px;">

    </div>
</div>
</div>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="static/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="static/bootstrap.min.js"></script>
<script src="static/echarts.min.js"></script>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var chart_1 = echarts.init(document.getElementById('sales_wrap'));
var sales_data = $:sales_data;
var option_1 = {
    title:{
        text:'71公司月销售额',
        subtext:'销售额(单位:万)'
    },
    xAxis:{
        type:'category',
        data:sales_data['category']
    },
    yAxis:{},
    series:[
        {
            'name':'销售额',
            type:'bar',
            data:sales_data['data'],
            markPoint:{
                data:[
                    {type:"max",name:"最大值"},
                    {type:"min",name:"最小值"}
                ]
            },
            markLine:{
                data:[
                    {type:'average',name:'平均值'}
                ]
            }
        }
    ],
    tooltip:{
        trigger:'axis'
    },
    toolbox:{
        show:true,
        feature:{
            dataView:{},
            magicType:{type:['line','bar']},
            restore:{},
            saveAsImage:{}
        }
    }
};
chart_1.setOption(option_1);

var chart_2 = echarts.init(document.getElementById('source_wrap'));
var source_data = $:source_data;
var source_title = $:source_title;
var source_stat_data = $:source_stat_data;
var option_2 = {
    tooltip:{
        trigger:'item',
        formatter:'{a}<br/>{b}:{c}({d}%)'
    },
    legend:{
        orient:'vertical',
        left:10,
        data:source_title
    },
    series:[
        {
            name:'访问来源',
            type:'pie',
            radius:['40%','55%'],
            data:source_data,
            label:{
                formatter:'{a|{a}}\n {hr|}\n {b|{b}}: {c}{per|{d}}%',
                borderColor:'aaa',
                borderWidth:1,
                borderRadius:4,
                backgroundColor:'#eee',
                rich:{
                    a:{
                        color:'#999',
                        lineHeight:22,
                        align:'center'
                    },
                    hr:{
                        borderColor:'#aaa',
                        width:'100%',
                        borderWidth:0.5,
                        height:0
                    },
                    b:{
                        fontSize:16,
                        lineHeight:33
                    },
                    per:{
                        color:'#eee',
                        backgroundColor:'334455',
                        padding:[2,4],
                        borderRadius:3
                    }
                }
            }
        },
        {
            name:'访问来源',
            type:'pie',
            radius:[0, '30%'],
            data:source_stat_data,
            label:{
                position:'inner'
            },
            selectedMode:'single'
        }
    ]
};
chart_2.setOption(option_2);

var chart_3 = echarts.init(document.getElementById('order_wrap'));
var clue_data = $:clue_data;
var clue_title = $:clue_title;
var option_3 = {
    title:{
        text:'销售线索转化图'
    },
    tooltip:{
        trigger:'item',
        formatter:'{a}<br/>{b}:{c}%'
    },
    legend:{
        data:clue_title
    },
    toolbox:{
        show:true,
        feature:{
            dataView:{},
            restore:{},
            saveAsImage:{}
        }
    },
    series:[
        {
            name:'漏斗图',
            type:'funnel',
            data:clue_data,
            label:{
                position:'inner'
            },
            emphasis:{
                label:{
                    fontSize:20
                }
            }
        }
    ]
}
chart_3.setOption(option_3);
</script>
</body>
</html>
  • 13
    点赞
  • 139
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值