matplotlib 一张图多个图_?Matplotlib+Pandas:绘制温湿度对比图(2)

876f6d925868c266670fc09b74acc598.png

在​Matplotlib+Pandas:绘制温湿度对比图(1)中,绘制和优化了温湿度变化比较图,最终结果较为满意。发文后没过多久,有同学私聊我,给我发了一张图(如下所示),很洋洋得意的告诉我,他觉得两个子图太麻烦,试着试着用了一张图将我的前文可视化结果展示出来了。

我起初很欣喜,终于有学生会举一反三了,但是看着图,看着看着觉得不对劲了= =|||

14019b7f9277cfb51f0f1b8bec962681.png

乍一看,给人一种完美可视化结果的感觉,到底错在哪里呢?

上图,将温度与湿度用同一个坐标轴(纵轴)表示,默认了温度与湿度是同一个度量单位(量纲),犯了典型的常识错误!我们都知道温度单位是摄氏度,而湿度常用相对湿度表示,它没有单位,它是一个比值(百分比)。

因此,在绘制可视化结果时,应该用不同的坐标刻度表示,即图的左边和右边分别绘制相应属性的坐标刻度。

既然问题找到了,接下来进行“改错”。


Matplotlib中主次坐标轴画法

这句话读起来很高级,其实非常简单。直接上代码上图,进行直观学习

先上错误代码,分析错误原因,之后改正,加深映像

import  pandas as pd
import  matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

df = pd.read_excel('D:PycharmProjectsData exercises数据可视化数据.xlsx')
print(df)
x = df['时间']
y1 = df['温度']
y2 = df['湿度']

fig = plt.figure(figsize = (12,6))
plt.plot(x, y1)
plt.plot(x, y2)

plt.legend()

plt.xlabel('时间')
plt.ylabel('温度及湿度')
plt.title('温度湿度随时间变化走势图')
plt.xticks(rotation=-20)

plt.show()

在上述代码中,利用两次plt.plot()进行绘制操作,由于两次传入的值不同,因此,画出了两个曲线(温度、湿度),没问题,是正确的。

错误的地方在于没有分别设置X轴,Y轴,只基于Matplotlib中默认方式进行了展示。

解决办法:twinx()→作用是产生一个Y轴的镜面坐标系

例如,如下代码,将产生一个默认横纵坐标为[0, 1]的可视化界面

import  matplotlib.pyplot as plt

fig = plt.figure()
ax1 = plt.subplot()

plt.show()

7fd67cc56b40ee7cc27940b62de22958.png

接下来,利用twinx()进行镜像操作,代码和可视化结果如下

import  matplotlib.pyplot as plt

fig = plt.figure()
ax1 = plt.subplot()

ax2 = ax1.twinx()

plt.show()

b75735a577d3b09762fe6b6c85121b5e.png

ax2 = ax1.twinx()的意思是对ax1的坐标面进行镜像操作,产生一个镜像坐标面,该坐标面被保存在ax2中。

产生了想要的效果,接下来的操作就顺风顺水了(希望如此= =|||)

ax1.plot(x, y1, color='r')
ax2.plot(x, y2, color='b')

通过plot()可以向ax1和ax2坐标面给值,进行绘制,完整代码如下

import  pandas as pd
import  matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

df = pd.read_excel('D:PycharmProjectsData exercises数据可视化数据.xlsx')

x = df['时间']
y1 = df['温度']
y2 = df['湿度']

fig = plt.figure()
ax1 = plt.subplot()

ax2= ax1.twinx()

ax1.plot(x, y1, color='r')
ax2.plot(x, y2, color='b')

plt.show()

2503a4e57e18f04bd0e71138f1876416.png

有些人一看图,怎么觉得和第七讲最后的图差别很大?原因是第七讲的图被预先缩放了画布比例。给上述代码中fig = plt.figure()给定和第七讲内容一样的画布大小(因为第七讲中是两个子图共用一块画布,所有在这里需要将宽再缩小一倍,即长、宽分别为13和2)

fig = plt.figure(figsize = (13,2))

修改后再次出图,如下图所示,几乎和第七讲中最后的图没有区别,只不过这里是在一张图中显示两个属性随时间的变化情况,而第七讲中的是分别划分两个子图进行显示

55a0d930368644dc5c69738bedc3d48f.png

“洁癖”又犯了......上图实在太丑,我们继续优化。优化点还是两个:

第一,坐标轴标签以及刻度优化;第二,图例

(1)坐标轴标签标注以及刻度优化

对各个坐标轴进行标注,代码如下:

ax1.set_xlabel('时间')
ax1.set_ylabel('温度')
ax2.set_ylabel('湿度')

在这里,大家要记清楚一点!我们这个数据可视化图中共用X轴,那么X轴的标度是无法用前几课介绍的plt.xticks(rotation=-20)进行逆时针旋转二十度操作!

但是,网上有大神,秀了一波操作,可以用如下代码代替plt.xticks()进行共轴坐标轴的旋转,代码如下:

for xtick in ax1.get_xticklabels():
    xtick.set_rotation(-20)

非常的秀,由此可见,代码是非常灵活的!

坐标轴标签标注以及刻度优化代码如下:

import  pandas as pd
import  matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

df = pd.read_excel('D:PycharmProjectsData exercises数据可视化数据.xlsx')

x = df['时间']
y1 = df['温度']
y2 = df['湿度']

fig = plt.figure(figsize = (12,6))
ax1 = plt.subplot()

ax2= ax1.twinx()

ax1.plot(x, y1, color='r')
ax2.plot(x, y2, color='b')

ax1.set_xlabel('时间')
ax1.set_ylabel('温度')
ax2.set_ylabel('湿度')

for xtick in ax1.get_xticklabels():
    xtick.set_rotation(-20)

plt.show()

e8ab39aea94781de0bfdee0544817e38.png

(2)图例

这里我遇到一个坑,对于两个坐标平面,我连续用了两个legend()去做,但是每次只显示一个图例,刚开始以为是前一个图例覆盖了后一个图例,其实不然......原因是两个图例在默认情况下显示在了同一个位置,感官上是一个把一个掩盖了。折腾了半天,终于找到了解决办法,legend()的其中一个参数loc是给定图例在整个图上

例如legend(loc = 2)指定图例在图中的右上角显示,loc参数中一共是1~10,对应图中位置如下图所示:

22f968179c566056196598f2ce8cede5.png

添加图例后的代码及可视化结果如下所示:

import  pandas as pd
import  matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

df = pd.read_excel('D:PycharmProjectsData exercises数据可视化数据.xlsx')

x = df['时间']
y1 = df['温度']
y2 = df['湿度']

fig = plt.figure(figsize = (12,6))
ax1 = plt.subplot()

ax2= ax1.twinx()

ax1.plot(x, y1, color='r')
ax2.plot(x, y2, color='b')

ax1.set_xlabel('时间')
ax1.set_ylabel('温度')
ax2.set_ylabel('湿度')

for xtick in ax1.get_xticklabels():
    xtick.set_rotation(-20)

plt.show()

b74f17873a99d69f0fb27b1b67eadefc.png

作为一个追求完美的老师,上图中,图例是分散的,不符合我们的审美概念和习惯,图例应该是在一起显示,但是作为双Y轴图表,不能直接粗暴的使用

ax1.legend()
ax2.legend()

之前已经提到过,这样会发生覆盖现象

只能进行如下操作:

fig.legend(loc=1, bbox_to_anchor=(1,1), bbox_transform=ax1.transAxes)

这里给大家留个自学机会,去查阅legend()的参数及其作用


最终版,基于双Y轴可视化显示,代码及可视化结果如下(额外补充了图的标题)

import  pandas as pd
import  matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

df = pd.read_excel('D:PycharmProjectsData exercises数据可视化数据.xlsx')

x = df['时间']
y1 = df['温度']
y2 = df['湿度']

fig = plt.figure(figsize = (12,6))
ax1 = plt.subplot()

ax2 = ax1.twinx()

ax1.plot(x, y1, color='r')
ax2.plot(x, y2, color='b')

ax1.set_xlabel('时间')
ax1.set_ylabel('温度')
ax2.set_ylabel('湿度')

for xtick in ax1.get_xticklabels():
    xtick.set_rotation(-20)

fig.legend(loc=1, bbox_to_anchor=(1,1), bbox_transform=ax1.transAxes)

plt.show()

352a97a16e589040a33ef1bb39474f2a.png

越往后,坑越多,坑越多,学习的东西越多。需要消化的时间也越多~今天到此为止,喜欢的朋友们记得帮忙收藏点赞哦,谢谢~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值