今天是第一次写踩坑日记系列,这个系列用来记录在Python和R学习过程中遇到的问题和结果。今天介绍的是使用Python的matplotlib库绘制两个y轴图的一些基本用法与踩坑行为。希望可以帮助到大家,也希望大家可以给出建议,欢迎留言交流。
Matplotlib介绍
Matplotlib是Python数据分析中常用的可视化工具,也是其他高级绘图接口(如seaborn, HoloViews, ggplot等)和专业绘图工具(如Cartopy)的基础。Matplotlib可以创建出版质量的图形,制作交互式的图形,自定义视觉风格和布局,导出到多种文件格式,嵌入在JupyterLab和图形用户界面中。更多探索内容请查看Matplotlib官网或Matplotlib中文网。
安装
pip install matplotlib
绘图元素
以下是 Matplotlib 图形的组件,来自于Matplotlib官网,详细使用方法查看快速入门指南 — Matplotlib 3.7.1 文档。
设置标题或轴名称等文本标签内容时,如果含有中文字符出现乱码的情况,需要添加以下代码,如果仍然无法解决,可以尝试将SimHei
字体改为FangSong
等其他字体。
plt.rcParams['font.sans-serif']=['SimHei'] # 用来设置字体样式以正常显示中文标签(黑体)
如果数字为负数,也可能会乱码,解决方法为:
plt.rcParams['axes.unicode_minus']=False
Matplotlib提供了多种图形,包括基本的柱状图、折线图、散点图、箱线图、散点图、饼图等,还提供了极坐标图、3D图形等高级的可视化图形(如果不想看官方文档,可以查看知乎上的一篇文章学习绘制以上图形的基本方法),可以通过以上参数对图像细节进行修改,并且可以对各种图形进行组合。
双y轴图
画单y轴图
import numpy as np
import matplotlib.pyplot as plt
# 生成一些示例数据
x = np.arange(10)
y = np.random.randint(0,20,10)
# 绘制折线图,设置颜色
plt.plot(x,y,color='blue')
# 设置x轴和y轴的标签,指明坐标含义
plt.xlabel('x轴', fontdict={'size': 16})
plt.ylabel('y轴', fontdict={'size': 16})
#设置图标题
plt.title('折线图')
# 设置中文显示
plt.rcParams['font.sans-serif']=['SimHei']
#展示图片
plt.show()
#画柱状图
plt.bar(x,y,color='blue')#只要将以上代码中的`plot`改为`bar`
双y轴折线图
import numpy as np
import matplotlib.pyplot as plt
# 生成一些示例数据
x = np.arange(10)
y1 = np.random.randint(10, size=10)
y2 = np.random.randint(10, size=10)
# 创建一个图形和两个y轴
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
#绘制折线图
line1 = ax1.plot(x, y1,label='y1轴', color='royalblue', marker='o', ls='-.')
line2 = ax2.plot(x, y2, label='y2轴', color='tomato', marker=None, ls='--')
# 设置x轴和y轴的标签,指明坐标含义
ax1.set_xlabel('x轴', fontdict={'size': 16})
ax1.set_ylabel('y1轴',fontdict={'size': 16})
ax2.set_ylabel('y2轴',fontdict={'size': 16})
#添加图表题
plt.title('双y轴折线图')
#添加图例
plt.legend()
# 设置中文显示
plt.rcParams['font.sans-serif']=['SimHei']
#展示图片
plt.show()
解决图例 通过以上方式设置的图例没有y1轴
,并且也没有出现报错信息,说明两个图例都显示出来的,很有可能就是y2轴
的图例将y1轴
图例覆盖了。通过将两轴的图例分开显示后证明确实是覆盖掉了
#将`plt.legend()`改为以下代码
ax1.legend(loc='upper right')
ax2.legend(loc='upper left')
但是两个图例分开显示也太丑了,还是希望可以将图例组合到一起
lines = line1 + line2
labels = [h.get_label() for h in lines]
plt.legend(lines, labels, loc='upper right')
设置轴 感觉这样看着有点不方便,如果把轴和线的颜色一致可能要好看一些
#设置轴标签颜色
ax1.tick_params('y', colors='royalblue')
ax2.tick_params('y', colors='tomato')
#设置轴颜色
ax1.spines['left'].set_color('royalblue')
ax2.spines['left'].set_color('royalblue')
ax1.spines['right'].set_color('tomato')
ax2.spines['right'].set_color('tomato')
两个y轴的颜色改变确实要好看一点,但是上轴线有点突兀,把它去掉
ax1.spines['top'].set_visible(False)
ax2.spines['top'].set_visible(False)
柱状图+折线图
把上边的y2改为柱状图,绘制柱状图与折线图双y轴图
import numpy as np
import matplotlib.pyplot as plt
# 生成一些示例数据
x = np.arange(10)
y1 = np.random.randint(10, size=10)
y2 = np.random.randint(10, size=10)
# 创建一个图形和两个y轴
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
#绘制图形
bar = ax1.bar(x, y1,label='y1轴', color='tomato', width=0.4)
line = ax2.plot(x, y2,label='y2轴', color='royalblue', marker='o', ls='-.')
# 设置x轴和y轴的标签,指明坐标含义
ax1.set_xlabel('x轴', fontdict={'size': 16})
ax1.set_ylabel('y1轴',fontdict={'size': 16})
ax2.set_ylabel('y2轴',fontdict={'size': 16})
#添加图表题
plt.title('双y轴折线图')
#添加图例
lines = line + bar
labels = [h.get_label() for h in lines]
plt.legend(lines, labels, loc='upper right')
#设置轴标签颜色
ax1.tick_params('y', colors='royalblue')
ax2.tick_params('y', colors='tomato')
#设置轴颜色
ax1.spines['left'].set_color('royalblue')
ax2.spines['left'].set_color('royalblue')
ax1.spines['right'].set_color('tomato')
ax2.spines['right'].set_color('tomato')
#去掉上轴线
ax1.spines['top'].set_visible(False)
ax2.spines['top'].set_visible(False)
# 设置中文显示
plt.rcParams['font.sans-serif']=['SimHei']
#展示图片
plt.show()
哎嗨,报错了。matplotlib柱状图的返回值是一个BarContainer元组对象,而折线图的返回值是一个Line2D列表对象。
使用matplotlib.pyplot.plot()函数来绘制一条折线,并将其返回值赋给一个变量,需要注意plot()函数返回的是一个包含一个Line2D对象的列表,而不是一个Line2D对象本身。所以,你需要在变量后面加上一个逗号,或者在使用get_label()方法时指定列表的索引为0,才能正确地获取Line2D对象的标签。所以将以上#绘制图形
模块改为
#绘制图形
bar = ax1.bar(x, y1,label='y1轴', color='tomato', width=0.4)
line, = ax2.plot(x, y2,label='y2轴', color='royalblue', marker='o', ls='-.')
好了,今天的踩坑日记就到这里了,对于图的其它修改细节,大家可以自己尝试一下,多试试总能发现不同的坑。
本文由 mdnice 多平台发布