子图大标题设置问题

1.前言

我们在日常画图的过程中经常会发现我们能对每一个子图进行标题设置,但是想设置一个大标题来概括这个可视化视图的时候却无能为力。典型情况如下图所示:

Python matplotlib title 加粗 matplotlib的title_可视化


对于上图很显然我们希望用一个大标题来概括这两个子图,比方说“numpy正弦、余弦画图”。

2.解决方案

2.1解决方案1

对于上面的问题我们可以使用suptitle方法设置中心大标题,切记只有Figure对象才拥有该方法。该方法参数如下:

参数说明:

suptitle(self, t, **kwargs)
参数1:t:字符型,指定标题
参数2:x:0-1之间浮点型,指定在figure坐标系下的标题横坐标
参数3:y:0-1之间浮点型,指定在figure坐标系下的标题纵坐标
参数4:horizontalalignment,指定文本相对于(x,y)的水平对齐方式。ha {‘center’,‘left’,‘right’}
参数5:verticalalignment,指定文本相对于(x,y)的垂直对齐方式。va {‘top’,‘center’,‘bottom’,‘baseline’}
参数6:fontsize:指定标题字体大小
参数7:fontweight:0-1000范围内的数值,指定字体重量,例:半粗体
参数8:**kwargs:指定接收FontProperties
返回值1:返回标题的Text实例


参数详解:
  1. x和y参数都是相对比例而不是绝对距离所以只能是0-1之间,默认值为x=0.5,y=0.98。
  2. ha、va参数指定的水平、垂直对齐方式对齐的点就是x、y参数指定的位置,如果不更改y=0.98那么va最好使用其默认值top,再次不建议更改任何位置参数,默认的已经足够优秀了。
  3. FontProperties包含了fontsize和fontweight参数,如果同时指定了这两个参数,那么会相互覆盖,谁在后面指定谁生效。
  4. FontProperties可以指定多种字体参数,包括拉伸、样式等。详见参考链接

2.1.1解决示例

对于前言所指图片添加大标题“numpy正弦、余弦画图”,示例程序如下:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置支持中文
plt.rcParams['axes.unicode_minus'] = False  # 设置-号
import numpy as np

#初始化数据和图框
figure, (ax1, ax2) = plt.subplots(1, 2)
X = np.linspace(0, 2 * np.pi, num=100)
Y1 = np.sin(X)
Y2 = np.cos(X)

#画sin
ax1.axhline(color='gray', linewidth=3)
ax1.plot(Y1, color='blue')
ax1.set_title('np.sin', fontsize=30)
ax1.set_xlabel('X', fontsize=25)
ax1.set_ylabel('sin(x)', fontsize=25)

#画cos
ax2.axhline(color='gray', linewidth=3)
ax2.plot(Y2, color='#FF0000')
ax2.set_title('np.cos', fontsize=30)
ax2.set_xlabel('X', fontsize=25)
ax2.set_ylabel('cos(x)', fontsize=25)

figure.suptitle('numpy正弦、余弦画图', fontsize=35)
plt.show()
画图结果如下:

Python matplotlib title 加粗 matplotlib的title_可视化_02


2.1.2FontProperties覆盖示例

首先我们先传入fontsize参数指定标题的绝对大小35,然后再传入FontProperties中的size参数指定绝对大小15。示例程序如下:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置支持中文
plt.rcParams['axes.unicode_minus'] = False  # 设置-号
import numpy as np

#初始化数据和图框
figure, (ax1, ax2) = plt.subplots(1, 2)
X = np.linspace(0, 2 * np.pi, num=100)
Y1 = np.sin(X)
Y2 = np.cos(X)

#画sin
ax1.axhline(color='gray', linewidth=3)
ax1.plot(Y1, color='blue')
ax1.set_title('np.sin', fontsize=30)
ax1.set_xlabel('X', fontsize=25)
ax1.set_ylabel('sin(x)', fontsize=25)

#画cos
ax2.axhline(color='gray', linewidth=3)
ax2.plot(Y2, color='#FF0000')
ax2.set_title('np.cos', fontsize=30)
ax2.set_xlabel('X', fontsize=25)
ax2.set_ylabel('cos(x)', fontsize=25)

figure.suptitle('numpy正弦、余弦画图', fontsize=35, size=15)	#先传入fontsize再传入size
plt.show()
画图结果如下:

Python matplotlib title 加粗 matplotlib的title_Text_03


紧接着我们吧这两个参数传递顺序颠倒,看看效果。

画图结果如下:

Python matplotlib title 加粗 matplotlib的title_数据可视化_04


很明显我们看到了覆盖效果,所以该参数只用传递一个便可。对于子图间距的问题详见参考链接


2.1.3x、y参数示例

为了验证x、y传递的是比例,我们将传递x=0.5,y=0.5来看看是否是在图框中间出现标题。示例程序如下:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置支持中文
plt.rcParams['axes.unicode_minus'] = False  # 设置-号
import numpy as np

#初始化数据和图框
figure, (ax1, ax2) = plt.subplots(1, 2)
X = np.linspace(0, 2 * np.pi, num=100)
Y1 = np.sin(X)
Y2 = np.cos(X)

#画sin
ax1.axhline(color='gray', linewidth=3)
ax1.plot(Y1, color='blue')
ax1.set_title('np.sin', fontsize=30)
ax1.set_xlabel('X', fontsize=25)
ax1.set_ylabel('sin(x)', fontsize=25)

#画cos
ax2.axhline(color='gray', linewidth=3)
ax2.plot(Y2, color='#FF0000')
ax2.set_title('np.cos', fontsize=30)
ax2.set_xlabel('X', fontsize=25)
ax2.set_ylabel('cos(x)', fontsize=25)

Text = figure.suptitle(t='x=0.5, y=0.5', x=0.5, y=0.5, fontsize=35) #传递 x=0.5, y=0.5
Text.set_color('#FF0000')
plt.show()
画图结果如下:

Python matplotlib title 加粗 matplotlib的title_matplotlib_05


从上图可以看到我们的标题被放置到了图框中心,所以证明x、y参数传递的是比例而不是绝对距离。


2.1.4va参数示例

ha参数的选项{‘center’,‘left’,‘right’}很好理解,但是对于va参数的选项{‘top’,‘center’,‘bottom’,‘baseline’}就不是那么好理解了,首先我们传递va=bottom来看看和默认画图有什么不同之处。示例程序如下:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置支持中文
plt.rcParams['axes.unicode_minus'] = False  # 设置-号
import numpy as np

#初始化数据和图框
figure, (ax1, ax2) = plt.subplots(1, 2)
X = np.linspace(0, 2 * np.pi, num=100)
Y1 = np.sin(X)
Y2 = np.cos(X)

#画sin
ax1.axhline(color='gray', linewidth=3)
ax1.plot(Y1, color='blue')
ax1.set_title('np.sin', fontsize=30)
ax1.set_xlabel('X', fontsize=25)
ax1.set_ylabel('sin(x)', fontsize=25)

#画cos
ax2.axhline(color='gray', linewidth=3)
ax2.plot(Y2, color='#FF0000')
ax2.set_title('np.cos', fontsize=30)
ax2.set_xlabel('X', fontsize=25)
ax2.set_ylabel('cos(x)', fontsize=25)

Text = figure.suptitle(t='va=bottom', fontsize=35, va='bottom') #传递va=bottom
Text.set_color('#FF0000')
plt.show()
画图结果如下:

Python matplotlib title 加粗 matplotlib的title_Text_06


从上图我们可以看出va参数对齐的基准线就是y参数指定的看不见的线。bottom以它为底,top以他为顶,center以他为中心线,最后baseline选项指的是在一行文本中,大多数字母以基线为基准。baseline设置文本行中的所有字母都分享相同的基线。该值的效果常常与 bottom 值相同。不过,如果文本的字号各不相同,那么 baseline 的效果会更好。示例如下图所示:

Python matplotlib title 加粗 matplotlib的title_数据可视化_07


3.参考

  1. FontProperties文档
  2. 子图间距问题解决方案