日期:2023.5.10
用到的工具:Navicat(数据库软件)Navicat | 支持 MySQL、MariaDB、MongoDB、SQL Server、SQLite、Oracle 和 PostgreSQL 的数据库管理,IDLE(python),jupyter notebook,pyecharts
1、搭建mysql数据库,导入数据
1.安装mysql数据库,cmd输入命令mysql -V 查看mysql是否安装成功。
成功会显示mysql版本,若不成功输入pip install mysql 进行安装。
2.打开Navicat,创建数据库连接
创建数据库 display,创建表 data, 导入数据。
2、在 Python 中连接数据库,获取所需的数据
1.首先引入必要的相关开发包
#引入开发包
import pymysql.cursors
import pandas as pd
from pyecharts.charts import Bar,Gauge,Pie,Page,Funnel,Geo,Scatter3D,Tab,Timeline,Grid,Line
from flask import Flask, render_template
from pyecharts import options as opts
from jinja2.utils import markupsafe
from pyecharts.globals import CurrentConfig
from pyecharts.globals import ThemeType
import traceback
2.获取数据库连接,获取所需要的数据
# 获取数据库连接
db = pymysql.connect(host='localhost',
user='root',
password='123456',
db='display',
charset='utf8mb4')
try:
#获取会话指针
with db.cursor() as cursor:
#查询语句
sql = "select `ID`,`案件副类别`,`经济损失`,`作案手法`,`发案地点`,'受理时间' from `data`"
#查询所有行数
# count = cursor.execute(sql)
# print(count)
#查询前三条数据
# result = cursor.fetchmany(size=3)
# print(result)
cursor.execute(sql)
result = cursor.fetchall()
#执行结果转换为dataframe对象
df = pd.DataFrame(list(result),columns=['ID','案件副类别','经济损失','作案手法','发案地点','受理时间'])
df0 = df[['案件副类别','经济损失']]
df1 = df0.groupby('案件副类别').count() # 用于统计案件副类别各类别个数
df2 = df[['作案手法','经济损失']]
df3 = df2.groupby('作案手法').count() # 用于统计作案手法各类别个数
df4 = df[['ID','发案地点']]
df5 = df4.groupby('发案地点').count()#用于统计各地区发生案件数
finally:
db.close()
db = pymysql.connect(host='localhost',
user='root',
password='123456',
db='display',
charset='utf8mb4')
try:
#获取会话指针
with db.cursor() as cursor:
#查询语句
sql = "select `经济损失`,`受理时间` from `data`;"
cursor.execute(sql)
result = cursor.fetchall()
#执行结果转换为dataframe对象
df6 = pd.DataFrame(list(result),columns=['经济损失','受理时间'])
finally:
db.close()
这里遇到了一个难题,我想分析每年案件的发生数量,研究其的趋势,但是案件日期的格式是2017-10-08(year-month-day)的,需要对其进行剥离,仅获取年份。关键代码:
y=pd.to_datetime(x).strftime('%Y')
这是chatGPT对于该行代码的解释。详细代码如下:
list_year=[]
list_month =[]
for x in df6['受理时间']:
try:
#x = datetime.strptime(x,'%Y-%m-%d')
y = pd.to_datetime(x).strftime('%Y')
m = pd.to_datetime(x).strftime('%m')
list_year.append(y)
list_month.append(m)
except BaseException as e:
# 时间需要在pd的时间戳区间,否则会抛出异常
print(traceback.format_exc(limit=3))
df6['year'] = pd.Series(data=list_year) # 时间时2015 - 2019年
df6['month'] = pd.Series(data=list_month)
del df6['受理时间']
#print(df6.head(10))
dic = {}
for x in range(2015,2020):
month_list = []
df_year = df6[df6['year']==str(x)]
df_month = df_year.groupby('month').sum()
month_list.append(list(df_month.index))
month_list.append(list(df_month['经济损失']))
dic[x] = month_list
df7=df6[['经济损失','year']]
df8=df7.groupby('year').count() #每年案发数量
数据获取完毕,接下来开始绘制图形
3.pyecharts画图
打开jupyter notebook,cmd输入jupyter notebook,会显示如下界面
复制网址,浏览器转到该网址
新建文件,开始编写图形代码
将前面的代码依次导入并运行
1.制作柱状图
#创建柱状图
def bar_base() -> Bar:
c = (
Bar(init_opts=opts.InitOpts(theme=ThemeType.WONDERLAND))
.add_xaxis(list(df1.index))
.add_yaxis("案件类别",
list(df1.iloc[:,0]),
markline_opts= opts.MarkLineItem(type_="average", name="平均值")
)
.set_global_opts(title_opts=opts.TitleOpts(title="各类别案件数量", subtitle="202004080308奈齐飞"))
.set_series_opts(itemstyle_opts=opts.ItemStyleOpts(color='#D028DA'))
)
return c
bar_base().render_notebook()
效果如下:
2.创建饼图
#创建饼图
def pie_base() -> Pie:
c = (
Pie(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
.add(
"",
# [list(z) for z in zip(Faker.choose(), Faker.values())],
[list(z) for z in zip(list(df3.index), list(df3.iloc[:, 0]))],
radius=["30%", "70%"],
)
.set_global_opts(
title_opts=opts.TitleOpts(title="各案件作案手法发生数"),
legend_opts=opts.LegendOpts(orient="vertical", pos_top="20%", pos_left="2%"),
)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}",color='#D028DA'))
)
return c
pie_base().render_notebook()
效果如下:
创建折线图
#创建折线图
def line_base() -> Line:
c = (
Line(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
.add_xaxis(list(df5.index))
.add_yaxis('各地发案数',list(df5.iloc[:, 0]))
.set_global_opts(title_opts=opts.TitleOpts(title="各地区发生案件数"))
)
return c
line_base().render_notebook()
效果如下:
def line_trend() -> Line:
c = (
Line(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
.add_xaxis(list(df8.index))
.add_yaxis('各年份发案数量走势图',list(df8.iloc[:, 0]))
.set_global_opts(title_opts=opts.TitleOpts(title="各年份发案数量走势图"))
)
return c
line_trend().render_notebook()
效果如下:
4.利用pyecharts中的page布局。将多个模块垂直组合到一个页面中
#利用pyecharts中的page布局。将多个模块垂直组合到一个页面中
def page_draggable_layout():
page = Page(layout=Page.DraggablePageLayout)
page.add(
bar_base(),
pie_base(),
line_base(),
line_trend(),
)
page.render("page_draggable_layout.html") #返回的页面名称,可以更改
#生成成功后,拖拽图表到合适的位置,保存,将保存的文件复制到代码文件路径下
if __name__ == "__main__":
page_draggable_layout()
生成成功后,当前文件夹下会生成page_draggable_layout.html,用浏览器打开,会获得4个垂直分布的图表可以对其进行拖拽(右边框和下边框),构建自己喜欢的布局
布局完成效果如下:
无法长截屏所以分三部分截图了。
然后点击页面左上角的save config按钮,保存至该文件所在的文件夹下
然后修改之前的代码
#生成成功后,拖拽图表到合适的位置,保存,将保存的文件复制到代码文件路径下
if __name__ == "__main__":
#page_draggable_layout()
Page.save_resize_html("page_draggable_layout.html",cfg_file="chart_config.json", dest="my_new_charts.html")
运行新的代码,会生成布局后的网页my_new_charts.html,浏览器打开查看效果(这里放的是缩略图50%)
5.将生成的html文件复制到www文件夹下,用php发布网站
我将这个文件名改为了index.php,这样打开浏览器转到127.0.0.1就会出现该网页
(这个图片是用最初做的代码实现的,感觉这个更美观一些,不影响观看)
结语:
本次实战运用了python+pyecharts+web的相关知识,算是一次对所学知识的综合运用和检验,其中数据的转换和获取是比较难搞的点,这也暴露出对于python掌握的不够牢靠,后续需要多加学习。另外,这次作业用到了ChatGPT,解答了我一些调试程序上遇到的问题,真的挺好用的,以后可以多了解了解ChatGPT,最好是能灵活运用。总体来说,这次作业的收获还是蛮大,谢谢那些在学习上给我提供帮助的老师同学。
版权归原作者 夏璃夜茉 所有, 如有侵权,请联系我们删除。