前面我们学习了Matplotlib的绘图流程和常用设置以及常见统计图的绘制方法。
同时,我们也发现Matplotlib绘制出的图形中会存在一些问题,例如:如何绘制双Y轴坐标系?如何去掉图形默认的边框?以及如何移动坐标到指定位置?
在进行数据分析时,有时候我们需要在同一个坐标图中比较两种数据在时间序列上的关系。
由于两种数据的单位和数据并不统一,也是不同的类型的数据,因此我们不能用一个Y轴来共同衡量两类不同的数据,这时候我们就需要绘制双Y轴图。
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
# 设置全局字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
datas = pd.read_excel(r'C:\Users\lin-a\Desktop\data\600001SH.xlsx')
# 将日期转换为时间戳,并设置为行索引
datas.index=pd.to_datetime(datas['日期'])
# 获取二月份的数据
feb_datas = datas['2015-02']
# 绘制图形
fig = plt.figure(figsize=(20,8),dpi=80)
ax = fig.add_subplot(111)
x = feb_datas.index.tolist()
# 将时间转换为字符串
x2 = [time.strftime('%Y-%m-%d') for time in x]
lin1 = ax.plot(x2,feb_datas['收盘价(元)'].values.tolist(),label='收盘价',color='red')
ax.legend(loc='upper left')
ax.set_ylabel("收盘价(元)")
ax.set_xlabel("日期")
plt.show()
以上的代码中:有add_subplot(),这个与plot()有什么异同呢?
plot是绘图,subplot是子图,整体不偏离这个框架。
fig.add_subplot(111)
此处,fig= plt.figure()是一个对象。
其中参数111,指的是将图像分成1行1列,此子图占据从左到右从上到下的1位置。
plt.subplot(234)
将画布分成2行3列,取从左到右,从上到下第4个位置。
两者本质是一样的,不同在于add_subplot是面向对象,subplot是面向函数
我们的目的是研究二月份某公司的每日收盘价以及对应的成交量,所以为方便分析,需要在一个双Y轴坐标图中同时绘制出收盘价和成交量的时间序列图。
双y轴绘制的关键函数是twinx(),twinx()函数表示共享X轴,共享表示的是X轴使用同一刻度线。
每日收盘价的折线图,我们已经绘制出来了,现在要使用twinx()绘制另外一条成交量折线图:
%matplotlib inline
from matplotlib import pyplot as plt
import pandas as pd
# 设置全局字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 导入数据
data = pd.read_excel(r'C:\Users\lin-a\Desktop\data\600001SH.xlsx')
# 查看数据的基本特征
print(data.shape)
# 将日期设置为数据的索引,便于使用日期选择数据
data.index = data['日期']
# 获取2月的数据
feb_data = data['2015-02']
# 获取x,y轴的数据
y = feb_data['收盘价(元)'].values.tolist()
y2 = feb_data['成交量(股)'].values.tolist()
x = feb_data.index.strftime('%Y-%m-%d').tolist()
# 设置画布大小
fig = plt.figure(figsize=(20,8),dpi=80)
# 设置ax对象
ax = fig.add_subplot(111)
ax2 = ax.twinx()
# 设置标题
plt.title('收盘价与成交量双曲线图')
# 设置第一条——收盘价曲线
line1 = ax.plot(x,y,label='收盘价',color='red')
ax.set_xlabel('日期')
ax.set_ylabel('收盘价(元)')
#设置图例
ax.legend(loc='upper left')
# 设置第二条——成交量曲线
line2 = ax2.plot(x,y2,label='成交量')
ax2.set_ylabel('成交量(股)')
# 设置图例
ax2.legend(loc='upper left')
# 绘制网格
ax.grid(linestyle='--',alpha=0.5)
plt.show()
(105, 13)
因为是共享X轴,所以只用ax.set_xlabel()就可以设置X轴的标题。
由于Y轴不共享,所以每一个坐标系的Y轴标题都要使用set_xlabel()方法设置一次。
代码中,我们设置了两次图例的显示,所以出现了两个图例重叠的现象,所以我们需要合并图例。合并图例的方法就是仅使用一个轴的legend()函数。
%matplotlib inline
from matplotlib import pyplot as plt
import pandas as pd
# 设置全局字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 导入数据
data = pd.read_excel(r'C:\Users\lin-a\Desktop\data\600001SH.xlsx')
# 查看数据的基本特征
print(data.shape)
# 将日期设置为数据的索引,便于使用日期选择数据
data.index = data['日期']
# 获取2月的数据
feb_data = data['2015-02']
# 获取x,y轴的数据
y = feb_data['收盘价(元)'].values.tolist()
y2 = feb_data['成交量(股)'].values.tolist()
x = feb_data.index.strftime('%Y-%m-%d').tolist()
# 设置画布大小
fig = plt.figure(figsize=(20,8),dpi=80)
# 设置ax对象
ax = fig.add_subplot(111)
ax2 = ax.twinx()
# 设置标题
plt.title('收盘价与成交量双曲线图')
# 设置第一条——收盘价曲线
line1 = ax.plot(x,y,label='收盘价',color='red')
ax.set_xlabel('日期')
ax.set_ylabel('收盘价(元)')
#设置图例
# ax.legend()
# 设置第二条——成交量曲线
line2 = ax2.plot(x,y2,label='成交量')
ax2.set_ylabel('成交量(股)')
# 设置图例
# ax2.legend()
# 合并图例
lns = line1+line2
labs = [l.get_label() for l in lns]
ax.legend(lns,labs,loc='upper left')
# 绘制网格
ax.grid(linestyle='--',alpha=0.5)
plt.show()
(105, 13)
以上新增的代码为:
# 合并图例
lns = line1+line2
labs = [l.get_label() for l in lns]
ax.legend(lns,labs,loc='upper left')
line1和line2分别是两个绘图方法plot()的返回值,即折线对象。需要注意的是,lin1和lin2的类型是list。
legend()方法可以指定图例中有哪些值,第一个参数lns表示将图中的多个线以列表的形势传进去,第二个参数labs表示将图例的名字以列表的形势传进去。
上图中,一个是Matplotlib默认绘制出的图像,另一个是修改了Matplotlib的一些默认显示方式。
经过前面的学习我们发现,Matplotlib在绘制图形的时候会默认显示上面和右侧的边框,以及坐标轴的颜色默认是黑色。
如果想要去掉默认的边框,通过plt.gca()获得当前的Axes对象。
ax = plt.gca()
接着使用spines属性获取到对应的位置。
ax.spines['right']
通过set_color('none’方法可设置边框的颜色。
ax.spines['right'].set_color('none')
对于颜色的设置,none表示无色,也可以用red、blue等样式的英语单词或者是十六进制的颜色值#0000FF。
%matplotlib inline
import matplotlib.pyplot as plt
y = range(0,14,2)
x = [-3,-2,-1,0,1,2,3]
# 获取当前图表的图像
ax = plt.gca()
# 设置当前图形的边框颜色
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('red')
ax.spines['left'].set_color('#0000FF')
plt.plot(x,y)
plt.show()
我们已经成功的设置边框的颜色,但是还有一个问题就是坐标轴的交叉点也是默认设置的。
如果想要X轴的0点,和Y轴的0点交叉,需要使用set_position方法移动坐标轴的位置。
ax.spines['bottom'].set_position(('data',0))
%matplotlib inline
import matplotlib.pyplot as plt
y = range(0,14,2)
x = [-3,-2,-1,0,1,2,3]
# 获取当前图表的图像
ax = plt.gca()
# 设置当前图形的边框颜色
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('red')
ax.spines['left'].set_color('#0000FF')
# 移动左边框和底部边框
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))
plt.plot(x,y)
plt.show()
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# 在指定间隔内返回均匀间隔的数字
x = np.linspace(-np.pi,np.pi,num=256)
# 正弦函数
y = np.sin(x)
# 画图,使用不同颜色和线条
plt.plot(x,y,color='red',linewidth=1)
# 获取当前图表的图像
ax = plt.gca()
# 设置图形的包围线
ax.spines['right'].set_color('none')
ax.spines['left'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('none')
# 设置不显示坐标轴刻度
plt.xticks([])
plt.yticks([])
plt.show()
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# 在指定间隔内返回均匀间隔的数字
x = np.linspace(-np.pi,np.pi,num=256)
# 正弦函数
y = np.sin(x)
# 设置画布大小
fig = plt.figure(figsize=(20,15),dpi=80)
# 画图,使用不同颜色和线条
plt.plot(x,y,color='red',linewidth=1)
# 获取当前图表的图像
ax = plt.gca()
# 设置图形的包围线
ax.spines['right'].set_color('none')
ax.spines['left'].set_color('black')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('black')
# 移动坐标轴
ax.spines['left'].set_position(('data',0))
ax.spines['bottom'].set_position(('data',0))
# 添加网格线
ax.grid(linestyle='--',alpha=0.5)
plt.show()
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
# 设置全局字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 导入数据
data = pd.read_excel(r'C:\Users\lin-a\Desktop\data\Commerce.xls')
# 查看数据基本特征
print(data.shape)
data
# 将日期设置为索引,便于选择2018年的数据
data.index = data['订单日期']
# 选取2018年的数据
data_18 = data['2018']
# 选择2017年的数据
data_17 = data['2017']
# 各地区2017年、2018年销售额
area_sales18 = data_18.groupby('地区')['销售额'].sum()
area_sales17 = data_17.groupby('地区')['销售额'].sum()
# 增长率
growth_rate = (area_sales18-area_sales17)/area_sales17
# 设置画布大小
fig = plt.figure(figsize=(20,8),dpi=80)
# 获取图表的图像
ax = fig.add_subplot(111)
# 设置图像标题
plt.title('各地区销售额与增长率对比图')
# 绘制地区销售额柱状图
line1 = ax.bar(area_sales18.index,area_sales18.values,width=0.5)
# 设置x,y轴标签
ax.set_xlabel('地区')
ax.set_ylabel('销售额(元)')
# 添加柱形的标注
for rect in line1:
height = rect.get_height()
ax.text(rect.get_x()+rect.get_width()/2,height+10000,'{:.2f}'.format(height),ha='center')
# 绘制增长率曲线
ax2 = ax.twinx()
line2 = ax2.plot(area_sales18.index,growth_rate,color='red',marker='o',label='增长率')
ax2.legend(loc='upper right')
ax2.set_ylabel('增长率')
# 绘制网格
ax.grid(linestyle='--',alpha=0.5)
plt.show()
(9268, 19)