数据可视化实战【mysql+pyecharts+web】
日期:2023.5.10
用到的工具:Navicat(数据库软件)Navicat | 支持 MySQL、MariaDB、MongoDB、SQL Server、SQLite、Oracle 和 PostgreSQL 的数据库管理,IDLE(python),jupyter notebook,pyecharts
1、搭建mysql数据库,导入数据
安装mysql数据库,cmd输入命令mysql -V 查看mysql是否安装成功。
成功会显示mysql版本,若不成功输入pip install mysql 进行安装。
打开Navicat,创建数据库连接
创建数据库 display,创建表 data, 导入数据。
2、在 Python 中连接数据库,获取所需的数据
首先引入必要的相关开发包
#引入开发包import pymysql.cursorsimport pandas as pdfrom pyecharts.charts import Bar,Gauge,Pie,Page,Funnel,Geo,Scatter3D,Tab,Timeline,Grid,Linefrom flask import Flask, render_templatefrom pyecharts import options as optsfrom jinja2.utils import markupsafefrom pyecharts.globals import CurrentConfigfrom pyecharts.globals import ThemeTypeimport traceback
获取数据库连接,获取所需要的数据
# 获取数据库连接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_listdf7=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 cbar_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 cpie_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 cline_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 cline_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,最好是能灵活运用。总体来说,这次作业的收获还是蛮大,谢谢那些在学习上给我提供帮助的老师同学。
来源地址:https://blog.csdn.net/weixin_53144783/article/details/130592771
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341