Matplotlib系列之绘制双Y轴折线图和柱状图

为了有更明显的对比效果,有时候我们需要将两个不同的曲线放在同一张图中,一般来说,这两个曲线值是不太一样的,需要不同的刻度。这时候,我们可以用双Y轴进行表示。

本文主要介绍如何用matplotlib绘制双Y轴折线图和柱状图。

绘制双Y轴折线图

这里的关键点在于:ax2 = ax1.twinx()

  • twinx是添加y轴的坐标轴
  • twiny是添加x轴的坐标轴

同时,为了更加清晰,这里设置Y轴的刻度(tick)与标签(label)的颜色分别与其对应的曲线颜色相同,关键代码:

1
2
3
4
5
6
7
# 双Y轴标签颜色设置
ax1.yaxis.label.set_color(line1.get_color())
ax2.yaxis.label.set_color(line2.get_color())

# 双Y轴刻度颜色设置
ax1.tick_params(axis = 'y', colors = line1.get_color())
ax2.tick_params(axis = 'y', colors = line2.get_color())

下面是全部的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns


fig, ax1 = plt.subplots()

# 项目平均金额折线图
line1, = ax1.plot(df_year['year_'], df_year['fund_mean'],color = sns.xkcd_rgb["pale red"],linestyle = '-',label = '项目平均金额')
p1 = ax1.scatter(df_year['year_'], df_year['fund_mean'],color = sns.xkcd_rgb["pale red"],marker = 'v',s = 30,label = '项目平均金额')

# 项目总金额折线图
ax2 = ax1.twinx()
line2, = ax2.plot(df_year['year_'], df_year['fund_sum'],color = sns.xkcd_rgb["denim blue"],linestyle = '-',label = '项目总金额')
p2 = ax2.scatter(df_year['year_'], df_year['fund_sum'],color = sns.xkcd_rgb["denim blue"],marker = 'o',s = 30,label = '项目总金额')

# 坐标轴设置
ax1.set_xlim([1985,2020])
ax1.set_ylim([0,75])
ax2.set_ylim([0,2700000])

ax1.set_xlabel("年份",fontsize = 12)
ax1.set_ylabel("项目平均金额/(万元)",fontsize = 12)
ax2.set_ylabel("项目总金额/(万元)",fontsize = 12)
ax1.set_title("资助项目年份统计",fontsize = 14)

# 双Y轴标签颜色设置
ax1.yaxis.label.set_color(line1.get_color())
ax2.yaxis.label.set_color(line2.get_color())

# 双Y轴刻度颜色设置
ax1.tick_params(axis = 'y', colors = line1.get_color())
ax2.tick_params(axis = 'y', colors = line2.get_color())

# 图例设置
plt.legend(handles = [p1,p2])

plt.show()

绘制双Y轴柱状图

双Y轴柱状图绘制的关键在于处理柱形的间隔x1_list([0,1,2…])、x2_list([0.4,1.4,2.4…])、width(0.4)的关系

1
2
3
4
5
6
7
8
9
# 柱形的宽度
width = 0.4

# 柱形的间隔
x1_list = []
x2_list = []
for i in range(len(df_nan_plot1)):
x1_list.append(i)
x2_list.append(i + width)

双Y轴的其余设置与前面的双Y轴折线基本相同,唯一的不同点在于选取颜色的函数get_color()变为了get_facecolor()

下面是全部的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns


fig, ax1 = plt.subplots()

# 柱形的宽度
width = 0.4

# 柱形的间隔
x1_list = []
x2_list = []
for i in range(len(df_nan)):
x1_list.append(i)
x2_list.append(i + width)

# 绘制柱形图1
b1 = ax1.bar(x1_list, df_nan['项目数'],width=width,label='缺失项目数',color = sns.xkcd_rgb["pale red"],tick_label = df_nan['学科'])

# 绘制柱形图2---双Y轴
ax2 = ax1.twinx()
b2 = ax2.bar(x2_list, df['项目数'],width=width,label='总项目数',color = sns.xkcd_rgb["denim blue"])

# 坐标轴标签设置
ax1.set_title('资助金额字段缺失分析-学科',fontsize = 14)
ax1.set_xlabel('学科',fontsize=12)
ax1.set_ylabel('缺失项目数',fontsize=12)
ax2.set_ylabel('总项目数',fontsize=12)

# x轴标签旋转
ax1.set_xticklabels(ax1.get_xticklabels(),rotation = 25)

# 双Y轴标签颜色设置
ax1.yaxis.label.set_color(b1[0].get_facecolor())
ax2.yaxis.label.set_color(b2[0].get_facecolor())

# 双Y轴刻度颜色设置
ax1.tick_params(axis = 'y', colors = b1[0].get_facecolor())
ax2.tick_params(axis = 'y', colors = b2[0].get_facecolor())

# 图例设置
plt.legend(handles = [b1,b2])

# 网格设置
plt.grid('off')

plt.show()

----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡