由于临近期末,所以根据汽车销量排行做个了可视化大屏作为期末大作业,数据是某车帝爬来的。
使用到的技术:Flask、pymysql、pyecharts
pyecharts官网:pyecharts - A Python Echarts Plotting Library built with love.
数据的内容是非常枯燥的,尤其单纯的通过数据表面,不能够看到其深度的意义和代表。但若是能够依赖于数据可视化方法的原理,就可以在一定程度上颠覆更加枯燥的数据内容,通过图表、图像等各种特殊的方法进行呈现,就可以让数据的分析通过这些更生动的方法变得更加通俗易懂。
我也部署在了PythonAnywhere感兴趣的小伙伴可以看一下哟:汽车销量可视化大屏
好!废话不多说。直接上图!
数据
数据库一张表的car_sales:车名、图片、排名、销量、品牌名、厂商、车型、起售价、最高价、月份
本来我想通过requests和bs4库来爬取网页的数据,但是意外发现了某车帝的现成接口,所以我们直接调用接口返回的数据就好
import requests
import pymysql
import json
import time
def get_conn():
# 建立连接
conn = pymysql.connect(host="127.0.0.1",port=3380, user="root", password="root", db="car", charset="utf8")
# c创建游标
cursor = conn.cursor()
return conn, cursor
def close_conn(conn, cursor):
if cursor:
cursor.close()
if conn:
conn.close()
def get_data(url):
res = json.loads(requests.get(url).text)
return (res['data']['list'])
def insert_hotsearch(url,t,m):
cursor = None
conn = None
try:
conn,cursor = get_conn()
print(f"{time.asctime()}开始插入数据")
conn,cursor = get_conn()
sql = "insert into car_sales_copy1(`series_name`, `image`, `rank`, `count`, `brand_name`, `type`, `sub_brand_name`, `min_price`, `max_price`, `month`) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);"
ts = time.strftime("%Y-%m-%d %X")
for i in get_data(url):
series_name = i.get('series_name')
image = i.get('image')
rank = i.get('rank')
count = i.get('count')
brand = i.get('brand_name')
sub_brand_name = i.get('sub_brand_name')
min_price = i.get('min_price')
max_price = i.get('max_price')
cursor.execute(sql,(series_name,image,rank,count,brand,t,sub_brand_name,min_price,max_price,m))
conn.commit()
print(f"{time.asctime()}数据插入完毕")
except:
traceback.print_exc()
finally:
close_conn(conn,cursor)
if __name__ == "__main__":
# 这里大家根据自己选择想爬取的月份
months = ['202305','202304','202303','202302','202301']
data = {
'轿车': {
'start': 0,
'end': 6,
'car_type': ['微型车','小型车','紧凑型车','中型车','中大型车','大型车']
},
'SUV': {
'start': 10,
'end': 15,
'car_type': ['小型SUV','紧凑型SUV','中型SUV','中大型SUV','大型SUV']
},
'MPV': {
'start': 20,
'end': 25,
'car_type': ['小型MPV','紧凑型MPV','中型MPV','中大型MPV','大型MPV']
}
}
for month in months:
for d in data:
item = data.get(d)
for index,value in enumerate([i for i in range(item.get('start'),item.get('end'))]):
url = f'https://www.dongchedi.com/motor/pc/car/rank_data?aid=1839&app_name=auto_web_pc&count=100000&month={month}&rank_data_type=11&outter_detail_type={value}&nation=0'
print(month,d,item.get('car_type')[index])
insert_hotsearch(url,item.get('car_type')[index],month)
我听到很多小伙伴调侃说:“在 pyecharts 中,一切皆 Options。”
不过好像确实这样的。。。
Pyecharts的配置项按模块分为全局配置、系列配置
系列配置分为整体配置和局部配置,而新配置会覆盖旧配置。
具体的我们还是参考官网,说得很详细。然后官网也有很多示例,小伙伴们感兴趣可以康康哦。
好,接下来我们来看本项目分钟使用前后端分离的方式,在Flask使用pyecharts。
通过查询数据库的数据=>生成配置信息=>返回给前端。在前端引入echarts.js,初始化图表并配置。
ok,下面我们看来个本项目中的例子吧。
后端接口
from random import randrange
from flask import Flask, render_template
from pyecharts import options as opts
from pyecharts.charts import Bar
app = Flask(__name__, static_folder="templates")
def bar_base() -> Bar:
c = (
Bar()
.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
.add_yaxis("商家A", [randrange(0, 100) for _ in range(6)])
.add_yaxis("商家B", [randrange(0, 100) for _ in range(6)])
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="我是副标题"))
)
return c
@app.route("/")
def index():
return render_template("index.html")
# # 本项目的中国汽车销量柱状图
# @app.route('/barChina')
# def bar_china() -> Bar:
# """
# 返回中国汽车销量柱状图的配置信息
# :return: options
# """
# # 获取数据
# xdata, ydata = utils.get_data(1)
# newX = []
# for x in xdata:
# newX.append(x[0:5] + '-' + x[5:])
# c = (
# Bar()
# .add_xaxis(newX)
# .add_yaxis("", ydata, bar_width='35%')
# .set_series_opts(
# # 不显示标签
# label_opts=opts.LabelOpts(is_show=False, color='rgba(255,255,255,.6)'),
# # 设置线条颜色
# line_style_opts=opts.LineStyleOpts(color='rgba(255,255,255,.1)'),
# # 不显示线
# axis_line_opts=opts.AxisLineOpts(linestyle_opts=opts.LineStyleOpts(is_show=False)),
# # 设置圆角
# itemstyle_opts={"barBorderRadius": 5},
# )
# .set_global_opts(
# # 不显示图例
# legend_opts=opts.LegendOpts(is_show=False),
# # 提示窗设置
# tooltip_opts=opts.TooltipOpts(trigger='axis', axis_pointer_type='shadow'),
# # x轴设置
# xaxis_opts=opts.AxisOpts(
# type_='category',
# axistick_opts=opts.AxisTickOpts(
# is_align_with_label=True,
# ),
# # x轴标签设置
# axislabel_opts=opts.LabelOpts(
# color='rgba(255,255,255,.6)',
# font_size=12,
# ),
# # 轴线设置
# axisline_opts=opts.AxisLineOpts(
# is_show=False
# ),
# # 分割线
# splitline_opts=opts.SplitLineOpts(is_show=False)
#
# ),
# # 配置y轴
# yaxis_opts=opts.AxisOpts(
# # 坐标轴类型。可选:
# # 'value': 数值轴,适用于连续数据。
# # 'category': 类目轴,适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
# # 'time': 时间轴,适用于连续的时序数据,与数值轴相比时间轴带有时间的格式化,在刻度计算上也有所不同,
# # 例如会根据跨度的范围来决定使用月,星期,日还是小时范围的刻度。
# # 'log' 对数轴。适用于对数数据。
# type_='value',
# axistick_opts=opts.AxisTickOpts(is_show=False),
# axislabel_opts=opts.LabelOpts(
# color='rgba(255,255,255,.6)',
# font_size=12,
# ),
# splitline_opts=opts.SplitLineOpts(
# is_show=True,
# linestyle_opts=opts.LineStyleOpts(
# color='rgba(255,255,255,.1)'
# )
# )
# )
# )
#
# )
# # 网格对象(用于组合图表,不过这里我用来调整图表的位置)
# grid = Grid()
# grid.add(c, opts.GridOpts(pos_left="8%", pos_top="10px", pos_right="0%", pos_bottom="15%"),is_control_axis_index=True)
# # 获取全局 options,JSON 格式(JsCode 生成的函数带引号,在前后端分离传输数据时使用)
# return grid.dump_options_with_quotes()
@app.route("/barChart")
def get_bar_chart():
c = bar_base()
return c.dump_options_with_quotes()
if __name__ == "__main__":
app.run()
前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<div id="bar" style="width:1000px; height:600px;"></div>
<script>
$(
function () {
var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
$.ajax({
type: "GET",
url: "http://127.0.0.1:5000/barChart",
dataType: 'json',
success: function (result) {
chart.setOption(result);
}
});
}
)
</script>
</body>
</html>
好,各位小伙伴们,今天的分享就到这。
完整的源码:https://download.youkuaiyun.com/download/weixin_48625737/87931064