Python数据可视化(2)
前言
本文主要是对上一篇内容一些细节部分做下补充,对于叙述不足之处,在上一篇文章里面应该是有的(先说明一下,这里的代码主要是用Jupyter Notebook写的)。
一. Matplotlib
1.1 几个常见图形
# 导入相关库
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文显示问题
mpl.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
%matplotlib inline # 让图形直接显示在网页上
散点图
plt.figure(figsize=(10, 5)) # 设定画板的大小
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x) + np.random.random(len(x)) # 加个随机点(白噪音)
plt.title('sin(x) 散点图') # 写标题
plt.scatter(x, y, c='green') # 画散点图,c表示设定颜色。
plt.show() # 图形显示
散点图+曲线图+折线图
plt.figure(dpi=120) # 像素为120
plt.scatter(x, y, c='g', label='散点图')
plt.plot(x,y, 'r--', label='随机点')
plt.plot(x, np.sin(x) + 0.5, c='b', label='sin曲线')
plt.legend() # 在图中显示标签
plt.show()
柱状图
# np.seed(123) # 这样的话,生成的随机数都是一样的。
n = 12;
x = np.arange(n)
y1 = np.random.random(n)
y2 = np.random.random(n)
plt.bar(x, y1, color='y')
plt.bar(x, -y2, color='b')
# ha 表示左右位置, va 表示上下位置
for i,j in zip(x, y1):
plt.text(i, j+0.05, "%.2f"%j, ha='center', va='bottom')
for i,j in zip(x, y2):
plt.text(i, -j-0.05, "%.2f"%j, ha='center', va='top')
plt.ylim(-1.2, 1.2) # 限定 y 轴的取值范围
plt.title(r'$\alpha$') # 两个‘$’表示将使用LaTex格式
plt.show()
饼图
n = 20
z = np.ones(n)
plt.figure(figsize=(5, 5))
# autopct 展示比例(需要显示百分号的话使用 %%),
# explode 突出显示什么(其他设为0),当然份数要一样。
# labels 显示标签;labeldistance 表示标签距离
plt.pie(z, autopct='%.2f', explode=[0.1]*(n-1)+[0.3],
colors=['%f'%(i/n) for i in range(n)])
plt.title(r'饼图')
plt.show()
# 这里颜色可以设定自己喜欢的颜色,当然份数得一样。
1.2 Matplotlib 可视化例子:
以某个餐饮业企业的订单详情表数据为可视化对象
- dishes_name: 菜品名称
- counts: 菜品数量
- amounts: 菜品单价
- order_id: 订单号
- place_order_time: 下单时间
1.2.1 分析问题一:销售额随时间的变化情况
数据预处理
# 创建连接
import pandas as pd
from sqlalchemy import create_engine
# 这里root后面接自己的密码;@后面接你的localhost号,基本是一样的,
# 然后就是数据库名称;最后是你在创建数据库时,自己设定的编码格式。
con = create_engine('mysql+pymysql://root:1234567@127.0.0.1:3306/pyecharts_test?charset=utf8')
将数据导入 jupyter 然后进行复制
tmp1 = pd.read_sql('meal_order1', con=con)
tmp2 = pd.read_sql('meal_order2', con=con)
tmp3 = pd.read_sql('meal_order3', con=con)
# 将所得的数据进行合并。以列进行合并
data = pd.concat([tmp1, tmp2, tmp3], axis=0)
data.shape
计算收入,并生成新的列
data['price'] = data['counts'] * data['amounts']
data.columns
格式转换
# 把时间列标准化时间格式
data['time_slot'] = pd.to_datetime(data['place_order_time'])
# 输出这一天是周中的第几天,Monday=0, Sunday=6
data['dayofweek'] = data['time_slot'].dt.dayofweek
# 生成新的列
data['day'] = pd.DatetimeIndex(data['place_order_time']).day
# 以 day 为区分索引
data_gb = data[['day', 'price']].groupby(by='day')
price_num = data_gb.agg(np.sum) # 对两列数据进行求和
利用上面的数据进行画图
plt.scatter(range(1, 32), price_num, marker='D')
plt.plot(range(1, 32), price_num)
plt.title('2021年4月门店销售额趋势示意图')
plt.xticks(range(1, 32)[::7], range(1, 32)[::7]) # 这里设定七天为一个显示
plt.xlabel('日期')
plt.ylabel('销售额')
plt.text(price_num['price'].argmin(), price_num['price'].min(), '最小值为:' + str(price_num['price'].min())) # 对最小值进行显示
plt.show()
1.2.2 销售额与星期的关系
先进行分组
data_gb = data[['dayofweek', 'price']].groupby(by='dayofweek')
number = data_gb.agg(np.sum)
number
# price
# dayofweek
#0 40312.0
#1 33066.0
#2 42068.0
#3 31988.0
#4 37684.0
#5 139665.0
#6 138921.0
跟换索引,并开始画图
# 柱状图
number.index = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
plt.bar(range(1, len(number)+1), number['price'], width=0.5, alpha=0.5)
plt.xticks(range(1, len(number)+1), number.index)
for i,j in zip(range(1, len(number)+1), number['price']):
plt.text(i, j, '%i' % j, ha='center', va='bottom')
plt.title('星期与销售额之间的关系')
plt.xlabel('星期')
plt.ylabel('销售额')
plt.show()
# 饼状图
plt.figure(figsize=(5, 5))
plt.style.use('ggplot') # 使用ggplot的绘图形式,让图片形式更好看。
# autopct 展示占比, wedgeprops 字典形式展示这个环图,之前不是个饼图的嘛,
# width 表示环的宽度,edgecolor表示环图边界颜色
plt.pie(number['price'], labels=number.index, autopct='%.2f %%', wedgeprops=dict(width=0.7, edgecolor='w'))
plt.title('星期与销售额占比情况')
plt.show()
1.2.3 时间,订单量,销售额之间的关系
# 数据准备
data_gb = data[['order_id', 'price', 'day']].groupby(by='day')
def myfun(data):
return len(np.unique(data))
# agg 要是同时使用多个函数,要用字典形式
number = data_gb.agg({
'price':np.sum, 'order_id':myfun})
number
画特殊的散点图
# 这里 s 表示使用的数据越大,这个点(球)就约大。
plt.scatter(range(1, 32), number['price'], s=number['order_id'])
plt.title('订单量,销售额与时间的关系')
plt.xlabel('时间')
plt.ylabel('销售额')
plt.show()
二. Pyecharts 可视化
from pyecharts.charts import *
from pyecharts import options as opts
2.1 散点图
x = np.linspace(0, 10, 51)
y = np.sin(x)
y2 = np.cos(x)
point = (Scatter(init_opts=opts.InitOpts(width="720px",height="320px"))
.add_xaxis(xaxis_data=x)
.add_yaxis(series_name="sin(x)",y_axis=y)
.add_yaxis(series_name="cos(x)",y_axis=y2, label_opts=opts.LabelOpts(is_show=False)) # 这里表示数据不显示
)
point.render_notebook() # 直接在notebook上展示
2.2 折线图
line = (Line(init_opts=opts.InitOpts(width="720px",height="320px"))
.add_xaxis(xaxis_data=x)
.add_yaxis(series_name="sin(x)",y_axis=y,
# 是否显示散点对应的数据(默认显示)
label_opts = opts.LabelOpts(is_show=False))
.add_yaxis(series_name="cos(x)",y_axis=y2, label_opts = opts.LabelOpts(is_show=False))
.set_global_opts(title_opts=opts.TitleOpts(title='曲线'), # 设置全局变量
tooltip_opts=opts.TooltipOpts(axis_pointer_type='cross')) # 一个解释器,方便横纵轴对比
)
line.render_notebook()
# line.render() # 如果想生成一个html保存下来,可以指定绝对地址即可
2.3 饼图
num = [110, 136, 108, 48, 111, 112, 103]
lab = ['哈士奇', '萨摩耶', '泰迪', '金毛', '牧羊犬', '吉娃娃', '柯基']
# radius 可以用来画环图
pie = (Pie(init_opts=opts.InitOpts(width='720px', height='320px'))
.add(series_name='饼图', data_pair=[(i,j) for i,j in zip(lab, num)], radius=['40%', '75%'])) # 没有radius,就是个饼图了,里面表示设定的宽高比例
pie.render_notebook()
2.4 玫瑰图
num = [110, 136, 108, 48, 111, 112, 103]
lab = ['哈士奇', '萨摩耶', '泰迪', '金毛', '牧羊犬', '吉娃娃', '柯基']
# radius 可以用来画环图, rosetype 玫瑰图
pie = (Pie(init_opts=opts.InitOpts(width='720px', height='320px'))
.add(series_name='饼图', data_pair=[(i,j) for i,j in zip(lab, num)], rosetype='radius')) # 与饼图相比,就改了这个rosetype。
pie.render_notebook()
2.5 柱状图
num1 = [110, 136, 108, 48, 111, 112, 103]
num2 = [90, 110, 101, 70, 90, 120, 99]
lab = ['哈士奇', '萨摩耶', '泰迪', '金毛', '牧羊犬', '吉娃娃', '柯基']
bar = (Bar(init_opts=opts.InitOpts(width='720px', height='320px'))
.add_xaxis(xaxis_data=lab)
.add_yaxis(series_name='商家A', y_axis=num1)
.add_yaxis(series_name='商家B', y_axis=num2)
.set_global_opts(title_opts=opts.TitleOpts(title='各商家拥有的犬数量统计情况', subtitle='仅做学习使用'))
)
bar.render_notebook()
2.6 并行多图(上下)
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
line = (Line()
.add_xaxis(xaxis_data=x)
.add_yaxis(series_name='', y_axis=y,
label_opts=opts.LabelOpts(is_show=False))
)
point = (Scatter()
.add_xaxis(xaxis_data=x)
.add_yaxis(series_name='', y_axis=y,
label_opts=opts.LabelOpts(is_show=False))
)
grid = (Grid(init_opts=opts.InitOpts(width='720px', height='320px'))
.add(point, grid_opts=opts.GridOpts(pos_bottom='60%'))
.add(line, grid_opts=opts.GridOpts(pos_top='60%')))
grid.render_notebook()
2.7 并行多图(左右)
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
line = (Line()
.add_xaxis(xaxis_data=x)
.add_yaxis(series_name='', y_axis=y,
label_opts=opts.LabelOpts(is_show=False))
)
point = (Scatter()
.add_xaxis(xaxis_data=x)
.add_yaxis(series_name='', y_axis=y,
label_opts=opts.LabelOpts(is_show=False))
)
# 与上面一个图相比,就改了 pos_left, pos_right,即相对位置
grid = (Grid(init_opts=opts.InitOpts(width='720px', height='320px'))
.add(point, grid_opts=opts.GridOpts(pos_left='60%'))
.add(line, grid_opts=opts.GridOpts(pos_right='60%')))
grid.render_notebook()
2.8 柱状图与折线图的组合
num = [110, 136, 108, 48, 111, 112, 103]
lab = ['哈士奇', '萨摩耶', '泰迪', '金毛', '牧羊犬', '吉娃娃', '柯基']
bar = (Bar(init_opts=opts.InitOpts(width='720px', height='360px'))
.add_xaxis(xaxis_data=lab)
.add_yaxis(series_name='', y_axis=num)
)
lines = (Line()
.add_xaxis(xaxis_data=lab)
.add_yaxis(series_name='', y_axis=num,
label_opts=opts.LabelOpts(is_show=False)))
bar.overlap(lines).render_notebook()
三. Pyecharts 地理图标
导入数据和库
from pyecharts.charts import Geo
import pyecharts.options as popts
from common import *
3.1 中国地图
geo = (Geo()
.add_schema(maptype="china")
.add(series_name='',
data_pair=[(i,j) for i,j in zip(Faker.provinces, Faker.values())])
.set_global_opts(
title_opts=opts.TitleOpts(title='中国地图'),
visualmap_opts=opts.VisualMapOpts(
# is_piecewise=True # 表示左下角的数据显示是否连续表示
)
)
)
geo.render_notebook()
3.2 特效散点图
from pyecharts.globals import ChartType
geo = (Geo()
.add_schema(maptype="china")
.add(series_name='',
data_pair=[(i,j) for i,j in zip(Faker.provinces, Faker.values())],
type_=ChartType.EFFECT_SCATTER) # 特效之处
.set_global_opts(
title_opts=opts.TitleOpts(title='中国地图(特效散点图)'),
visualmap_opts=opts.VisualMapOpts(
is_piecewise=True # 表示左下角的数据显示是否连续表示
)
)
)
geo.render_notebook()
# 这里特效体现在,散点图中的每个点都会波纹闪动。
3.3 特效散点图:添加箭头
from pyecharts.globals import SymbolType
city_num = [('广州',105), ('成都',70), ('北京',99), ('西安',80)]
start_end = [('广州','成都'), ('广州','北京'), ('广州','西安')]
# 绘图实现
(
Geo()
.add_schema(maptype='china',
itemstyle_opts=opts.ItemStyleOpts(color='#323c48',
border_color='#111'))
.add('', data_pair=city_num, color='white')
# 对箭头进行设定,起始点,以及线的类型
.add('', data_pair=start_end, type_=ChartType.LINES,
# 对箭头进行设定,类型为箭头,箭头的颜色,以及箭头的大小
effect_opts=opts.EffectOpts(symbol=SymbolType.ARROW, color='blue', symbol_size=8))
).render_notebook()
3.4 广东的热力图
(
Geo()
.add_schema(maptype='广东')
.add(series_name='', data_pair=[(i,j) for i,j in zip(Faker.guangdong_city, Faker.values())],
type_=ChartType.HEATMAP)
.set_global_opts(visualmap_opts=opts.VisualMapOpts())
).render_notebook()
3.5 广东详情
from pyecharts.charts import Map
(
Map()
.add(series_name=r'', data_pair=[(i,j) for i,j in zip(Faker.guangdong_city, Faker.values())],maptype='广东')
.set_global_opts(visualmap_opts=opts.VisualMapOpts()) # 图片渲染
).render_notebook()
说明: 第三章所展示的代码所生成的图片在上一篇文章中都有的,在这里不做过多展示。而且在上文展示的关于微信好友的地域图,由于wxpy这个库被禁用了。因为微信网页登录端口关闭了,所以这个库基本上算是被禁了,这样微信无法登录导致微信好友在地图上展示的操作,目前还没有得到有效解决。如果后面成功了,可定第一时间发出来。
总结
本文主要是对上一篇文章的一个细节补充,当然了,代码可以直接拿去使用的,转载的话,麻烦写一下出处,谢谢大家。
最后安利一下华为云的服务(也有
个人/企业
免费版,可以先试用的。)
- 企业免费版
- 个人免费版
- 活动打折版
- 从下方图片或者这里链接进入还有其他优惠
溜了溜了,脑壳疼。Loading(44/100)。。。
转载:https://blog.csdn.net/Tomandjava/article/details/115902135
查看评论