Matplotlib从入门到精通04-文字图例尽眉目

简介: Matplotlib从入门到精通04-文字图例尽眉目

89ad83db786a4f1ebdc9a3db90545732.png


Matplotlib从入门到精通04-文字图例尽眉目


导入依赖设置中文坐标轴负号

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
import datetime
plt.rcParams['font.sans-serif'] = ['SimHei']   #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False   #用来正常显示负号

一.Figure和Axes上的文本

Matplotlib具有广泛的文本支持,包括对数学表达式的支持、对栅格和矢量输出的TrueType支持、具有任意旋转的换行分隔文本以及Unicode支持。


1.文本API示例¶

参考:https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.annotate.html#matplotlib.axes.Axes.annotate

下面的命令是介绍了通过pyplot API和objected-oriented API分别创建文本的方式。


46a9e1707dbf18f5d346c30a613efb5f_38f52a2fea7c46ccbdcd41f550bebf2a.png


通过一个综合例子,以OO模式展示这些API是如何控制一个图像中各部分的文本,在之后的章节我们再详细分析这些api的使用技巧


fig = plt.figure()
ax = fig.add_subplot()
# 分别为figure和ax设置标题,注意两者的位置是不同的
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')
# 设置x和y轴标签
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# 设置x和y轴显示范围均为0到10
ax.axis([0, 10, 0, 10])
# 在子图上添加文本
ax.text(3, 8, 'boxed italics text in data coords', style='italic',
        bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
# 在画布上添加文本,一般在子图上添加文本是更常见的操作,这种方法很少用
fig.text(0.4,0.8,'This is text for figure')
ax.plot([2], [1], 'o')
# 添加注解
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()

e87a15bb305ae9dc43c9b8a949cb5125_e710b1d3fd7148099fdca97201358a35.png


2.text - 子图上的文本¶

参考:https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.text.html#matplotlib.axes.Axes.text


text的用方式为


Axes.text(x, y, s, fontdict=None, **kwargs)

其中x,y为文本出现的位置,默认状态下即为当前坐标系下的坐标值,

s为文本的内容,

fontdict是可选参数,用于覆盖默认的文本属性,

**kwargs为关键字参数,也可以用于传入文本样式参数


重点解释下fontdict和**kwargs参数,这两种方式都可以用于调整呈现的文本样式,最终效果是一样的,不仅text方法,其他文本方法如set_xlabel,set_title等同样适用这两种方式修改样式。通过一个例子演示这两种方法是如何使用的。


fig = plt.figure(figsize=(10,3))
axes = fig.subplots(1,2)
# 使用关键字参数修改文本样式
axes[0].text(0.3, 0.8, 'modify by **kwargs', style='italic',
        bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10});
# 使用fontdict参数修改文本样式
font = {'bbox':{'facecolor': 'red', 'alpha': 0.5, 'pad': 10}, 'style':'italic'}
axes[1].text(0.3, 0.8, 'modify by fontdict', fontdict=font)
plt.show()

dab80b4421dc5062f1c0e3b84f2154f8_a9289fe2b3594b5cae80f079660caf16.png

text的参数可参考官方文档


4d19cacdfd64ad3f94d6bfcdab978de7_b488f23a11db45cfb639e9c815803378.png

3.xlabel和ylabel - 子图的x,y轴标签¶

参考:https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xlabel.html

xlabel的调用方式为


Axes.set_xlabel(xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)

ylabel方式类似,这里不重复写出。

其中xlabel即为标签内容,

fontdict和**kwargs用来修改样式,上一小节已介绍,

labelpad为标签和坐标轴的距离,默认为4,

loc为标签位置,可选的值为’left’, ‘center’, 'right’之一,默认为居中


# 观察labelpad和loc参数的使用效果
fig = plt.figure(figsize=(10,3))
axes = fig.subplots(1,2)
axes[0].set_xlabel('xlabel',labelpad=20,loc='left')
# loc参数仅能提供粗略的位置调整,如果想要更精确的设置标签的位置,可以使用position参数+horizontalalignment参数来定位
# position由一个元组过程,第一个元素0.2表示x轴标签在x轴的位置,第二个元素对于xlabel其实是无意义的,随便填一个数都可以
# horizontalalignment='left'表示左对齐,这样设置后x轴标签就能精确定位在x=0.2的位置处
axes[1].set_xlabel('xlabel', position=(0.2, 0), horizontalalignment='left');
plt.show()

b7beb39f4ebd5d938dde220ce602b890_630bc534397344cfa2742487a1708f1f.png

4.title和suptitle - 子图和画布的标题¶

title的调用方式为


Axes.set_title(label, fontdict=None, loc=None, pad=None, *, y=None, **kwargs)

其中label为子图标签的内容,fontdict,loc,**kwargs和之前小节相同不重复介绍

pad是指标题偏离图表顶部的距离,默认为6

y是title所在子图垂向的位置。默认值为1,即title位于子图的顶部。


suptitle的调用方式为figure.suptitle(t, **kwargs)

其中t为画布的标题内容


f

fig, ax = plt.subplots(1,2)
fruits = ['apple', 'blueberry', 'cherry', 'orange']
counts = [40, 100, 30, 55]
bar_labels = ['red', 'blue', '_red', 'orange']
bar_colors = ['tab:red', 'tab:blue', 'tab:red', 'tab:orange']
ax[0].bar(fruits, counts, label=bar_labels, color=bar_colors)
ax[0].set_ylabel('fruit supply')
ax[0].set_title('Fruit supply by kind and color')
ax[0].legend(title='Fruit color')
ax[1].set_title('空的title')
plt.show()

f7290a75f10b3951d1ea16f57b3d3c9c_d52c46bec1a74dccb16e067f1c9b2b65.png


5.annotate - 子图的注解¶

annotate的调用方式为


Axes.annotate(text, xy, *args, **kwargs)

其中text为注解的内容,

xy为注解箭头指向的坐标,

其他常用的参数包括:

xytext为注解文字的坐标,

xycoords用来定义xy参数的坐标系,

textcoords用来定义xytext参数的坐标系,

arrowprops用来定义指向箭头的样式

annotate的参数非常复杂,这里仅仅展示一个简单的例子,更多参数可以查看官方文档中的annotate介绍


fig, ax = plt.subplots(figsize=(3, 3))
x = [1, 3, 5, 7, 9]
y = [2, 4, 6, 8, 10]
annotations = ["A", "B", "C", "D", "E"]
ax.scatter(x, y, s=20)
for xi, yi, text in zip(x, y, annotations):
    ax.annotate(text,
                xy=(xi, yi), xycoords='data',
                xytext=(1.5, 1.5), textcoords='offset points')
plt.show()

02c77b76b48d39e1b8a703c07734afe1_38ff447c5392448ba9348f567f8bbb29.png


6.字体的属性设置¶

字体设置一般有全局字体设置和自定义局部字体设置两种方法。


为方便在图中加入合适的字体,可以尝试了解中文字体的英文名称,该链接告诉了常用中文的英文名称


#该block讲述如何在matplotlib里面,修改字体默认属性,完成全局字体的更改。
plt.rcParams['font.sans-serif'] = ['SimSun']    # 指定默认字体为新宋体。
plt.rcParams['axes.unicode_minus'] = False      # 解决保存图像时 负号'-' 显示为方块和报错的问题。
#局部字体的修改方法1
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plt.plot(x, label='小示例图标签')
# 直接用字体的名字
plt.xlabel('x 轴名称参数-楷体', fontproperties='KaiTi', fontsize=16)         # 设置x轴名称,采用楷体
plt.ylabel('y 轴名称参数-幼园', fontproperties='YouYuan', fontsize=14)         # 设置Y轴名称 采用幼园
plt.title('坐标系的标题-微软雅黑',  fontproperties='Microsoft YaHei', fontsize=20)         # 设置坐标系标题的字体 采用微软雅黑
plt.legend(loc='lower right', prop={"family": 'SimHei'}, fontsize=10) ;   # 小示例图的字体设置 采用黑体
plt.show()

5920d4247f5e0731728706974bf40c0c_ba52c6a367464204b1a6aaf722f1f6bb.png


二、Tick上的文本¶

设置tick(刻度)和ticklabel(刻度标签)也是可视化中经常需要操作的步骤,matplotlib既提供了自动生成刻度和刻度标签的模式(默认状态),同时也提供了许多让使用者灵活设置的方式。


1.简单模式¶

可以使用axis的set_ticks方法手动设置标签位置,使用axis的set_ticklabels方法手动设置标签格式

x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
# 使用axis的set_ticks方法手动设置标签位置的例子,该案例中由于tick设置过大,所以会影响绘图美观,不建议用此方式进行设置tick
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
axs[1].xaxis.set_ticks(np.arange(0., 10.1, 2.));
plt.show()

a6c7b8610670ed1c47a9acaa00eeb9a5_0d210cc9e18f4ad7b96784db30efa963.png


x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
# 使用axis的set_ticklabels方法手动设置标签格式的例子
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
tickla = [f'{tick:1.2f}' for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla)
plt.show()

c8dc2453a77eff41e30d1c832783952e_25330ac638f44751a5e6805ade173e2b.png


#一般绘图时会自动创建刻度,而如果通过上面的例子使用set_ticks创建刻度可能会导致tick的范围与所绘制图形的范围不一致的问题。

#所以在下面的案例中,axs[1]中set_xtick的设置要与数据范围所对应,然后再通过set_xticklabels设置刻度所对应的标签

#一般绘图时会自动创建刻度,而如果通过上面的例子使用set_ticks创建刻度可能会导致tick的范围与所绘制图形的范围不一致的问题。
#所以在下面的案例中,axs[1]中set_xtick的设置要与数据范围所对应,然后再通过set_xticklabels设置刻度所对应的标签
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(2, 1, figsize=(6, 4), tight_layout=True)
x1 = np.linspace(0.0, 6.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
axs[0].plot(x1, y1)
axs[0].set_xticks([0,1,2,3,4,5,6])
axs[1].plot(x1, y1)
axs[1].set_xticks([0,1,2,3,4,5,6])#要将x轴的刻度放在数据范围中的哪些位置
axs[1].set_xticklabels(['zero','one', 'two', 'three', 'four', 'five','six'],#设置刻度对应的标签
                   rotation=30, fontsize='small')#rotation选项设定x刻度标签倾斜30度。
axs[1].xaxis.set_ticks_position('bottom')#set_ticks_position()方法是用来设置刻度所在的位置,常用的参数有bottom、top、both、none
print(axs[1].xaxis.get_ticklines());
plt.show()

631585f56bc368416890781076b9ba66_ce2666828a7543f194b73821dd2d068a.png


2.Tick Locators and Formatters¶

除了上述的简单模式,还可以使用Tick Locators and Formatters完成对于刻度位置和刻度标签的设置。 其中Axis.set_major_locator和Axis.set_minor_locator方法用来设置标签的位置,Axis.set_major_formatter和Axis.set_minor_formatter方法用来设置标签的格式。这种方式的好处是不用显式地列举出刻度值列表。


set_major_formatter和set_minor_formatter这两个formatter格式命令可以接收字符串格式(matplotlib.ticker.StrMethodFormatter)或函数参数(matplotlib.ticker.FuncFormatter)来设置刻度值的格式 。


a) Tick Formatters

# 接收字符串格式的例子
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
    ax.plot(x1*10., y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
axs[0, 1].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('-%1.1f')
axs[1, 0].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
axs[1, 1].xaxis.set_major_formatter(formatter);
plt.show()

edbeab129e78023c0b25186cacf29c09_0a9a44c8562d4d3a9338c1f2d9914ffe.png

x1 = np.linspace(0.0, 6.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
# 接收函数的例子
def formatoddticks(x, pos):
    """Format odd tick positions."""
    if x % 2:
        return f'{x:1.2f}'
    else:
        return ''
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
ax.xaxis.set_major_formatter(formatoddticks)
plt.show()

cdd882eb4d9ced55a32b7a3ec63585a7_b5fe19f6caed443f8140e1ece4fda098.png


b) Tick Locators¶

在普通的绘图中,我们可以直接通过上图的set_ticks进行设置刻度的位置,缺点是需要自己指定或者接受matplotlib默认给定的刻度。

当需要更改刻度的位置时,matplotlib给了常用的几种locator的类型。如果要绘制更复杂的图,可以先设置locator的类型,然后通过axs.xaxis.set_major_locator(locator)绘制即可


locator=plt.MaxNLocator(nbins=7)#自动选择合适的位置,并且刻度之间最多不超过7(nbins)个间隔

locator=plt.FixedLocator(locs=[0,0.5,1.5,2.5,3.5,4.5,5.5,6])#直接指定刻度所在的位置

locator=plt.AutoLocator()#自动分配刻度值的位置

locator=plt.IndexLocator(offset=0.5, base=1)#面元间距是1,从0.5开始

locator=plt.MultipleLocator(1.5)#将刻度的标签设置为1.5的倍数

locator=plt.LinearLocator(numticks=5)#线性划分5等分,4个刻度


x1 = np.linspace(0.0, 6.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
# 接收各种locator的例子
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
    ax.plot(x1*10., y1)
locator = matplotlib.ticker.AutoLocator()
axs[0, 0].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.MaxNLocator(nbins=3)
axs[0, 1].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.MultipleLocator(5)
axs[1, 0].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.FixedLocator([0,7,14,21,28])
axs[1, 1].xaxis.set_major_locator(locator);
plt.show()

ba28576294e040d31a94e3321fb20c29_b587ffb462fc479db1f7abf8097ed199.png


此外matplotlib.dates 模块还提供了特殊的设置日期型刻度格式和位置的方式


x1 = np.linspace(0.0, 6.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
# 特殊的日期型locator和formatter
locator = mdates.DayLocator(bymonthday=[1,15,25])
formatter = mdates.DateFormatter('%b %d')
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70);
plt.show()

输出为:

95d0e7e39cdf169b0f116edadb4d396b_8861c759c9d24db2accb69302d093652.png


三、legend(图例)¶

legend组成即案例

在具体学习图例之前,首先解释几个术语:

legend entry(图例条目)

每个图例由一个或多个legend entries组成。一个entry包含一个key和其对应的label。

legend key(图例键)

每个legend label左面的colored/patterned marker(彩色/图案标记)

legend label(图例标签)

描述由key来表示的handle的文本

legend handle(图例句柄)

用于在图例中生成适当图例条目的原始对象


图例的绘制同样有OO模式和pyplot模式两种方式,写法都是一样的,使用legend()即可调用。

以下面的代码为例,在使用legend方法时,我们可以手动传入两个变量,句柄和标签,用以指定条目中的特定绘图对象和显示的标签值。

当然通常更简单的操作是不传入任何参数,此时matplotlib会自动寻找合适的图例条目。


fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend(handles = [line_up, line_down], labels = ['Line Up', 'Line Down']);
plt.show()

6739b2b16fea4c89a820caf9b76c9499_2d86bf6e677847c09e2987c91703c923.png


以上图为例,右侧的方框中的共有两个legend entry;两个legend key,分别是一个蓝色和一个黄色的legend key;两个legend label,一个名为‘Line up’和一个名为‘Line Down’的legend label


legend其他常用的几个参数如下:


设置图例位置

loc参数接收一个字符串或数字表示图例出现的位置

ax.legend(loc=‘upper center’) 等同于ax.legend(loc=9)


Location String Location Code

‘best’ 0

‘upper right’ 1

‘upper left’ 2

‘lower left’ 3

‘lower right’ 4

‘right’ 5

‘center left’ 6

‘center right’ 7

‘lower center’ 8

‘upper center’ 9

‘center’ 10


fig,axes = plt.subplots(2,4,figsize=(10,4))
for i in range(4):
    axes[0][i].plot([0.5],[0.5])
    axes[0][i].legend(labels='a',loc=i)  # 观察loc参数传入不同值时图例的位置
for i in range(4,8):
    t=i%4
    axes[1][t].plot([0.5],[0.5])
    axes[1][t].legend(labels='a',loc=i)  # 观察loc参数传入不同值时图例的位置
fig.tight_layout()
plt.show()

86697f2fc90fa5b3ec68bb47c44e6b07_ad8bcf03b9b2425694c8d60eb7f61a5d.png


设置图例边框及背景

fig = plt.figure(figsize=(10,3))
axes = fig.subplots(1,3)
for i, ax in enumerate(axes):
    ax.plot([1,2,3],label=f'ax {i}')
axes[0].legend(frameon=False) #去掉图例边框
axes[1].legend(edgecolor='blue') #设置图例边框颜色
axes[2].legend(facecolor='gray'); #设置图例背景颜色,若无边框,参数无效
plt.show()

f073e38e208505a9d780abfcb88ee618_db1f9a18baa74b2da7049006d4f54c6f.png


设置图例标题

fig,ax =plt.subplots()
ax.plot([1,2,3],label='label')
ax.legend(title='legend title');
plt.show()

bf37d69da33f41f1b50f33e3e7e8ad38_9e5794c9d4a64c9eb1368b975933e7ba.png


参考:

https://datawhalechina.github.io/fantastic-matplotlib/%E7%AC%AC%E4%B8%80%E5%9B%9E%EF%BC%9AMatplotlib%E5%88%9D%E7%9B%B8%E8%AF%86/index.html


https://matplotlib.org/stable/index.html


http://c.biancheng.net/matplotlib/data-visual.html


AI算法工程师手册

Task3:用极坐标系绘制玫瑰图&散点图和边际分布图的绘制


总结

本文主要是Matplotlib从入门到精通系列第4篇,本文介绍了Matplotlib的Figure和Axes上的文本设置,Tick的文本设置,legend图例设置,同时介绍了较好的参考文档置于博客前面,读者可以重点查看参考链接。本系列的目的是可以完整的完成Matplotlib从入门到精通。重点参考连接

相关文章
|
4月前
|
数据可视化 数据挖掘 C++
一文入门数分三剑客--Numpy、Pandas、Matplotlib
一文入门数分三剑客--Numpy、Pandas、Matplotlib
|
4月前
|
Python 容器
Matplotlib中的titles(标题)、labels(标签)和legends(图例)
本文讨论Python的Matplotlib绘图库中可用的不同标记选项。
63 0
|
10天前
|
搜索推荐 数据可视化 Python
Matplotlib图表中的数据标签与图例设置
【4月更文挑战第17天】这篇文章介绍了如何在Python的Matplotlib库中设置数据标签和图例,以增强图表的可读性和解释性。主要内容包括:使用`text`函数添加基本和自定义数据标签,以及自动和手动创建图例。图例的位置和样式可通过`loc`和相关参数调整。文章强调了数据标签和图例结合使用的重要性,提供了一个综合示例来展示实践方法。良好的图表设计旨在清晰有效地传达信息。
|
1月前
|
机器学习/深度学习 数据可视化 搜索推荐
12个最常用的matplotlib图例 !!
12个最常用的matplotlib图例 !!
33 1
|
1月前
|
机器学习/深度学习 数据可视化 数据挖掘
Python中的数据可视化:Matplotlib库入门与实践
在数据分析和机器学习领域,数据可视化是至关重要的一环。本文将介绍Python中常用的数据可视化库Matplotlib的基本用法和实践技巧,帮助读者快速掌握如何利用Matplotlib创建各种类型的图表,提升数据分析和展示的效果。
|
4月前
|
人工智能 数据可视化 算法
Matplotlib从入门到精通05-样式色彩秀芳华
Matplotlib从入门到精通05-样式色彩秀芳华
Matplotlib从入门到精通05-样式色彩秀芳华
|
4月前
|
人工智能 算法 API
Matplotlib从入门到精通03-布局格式定方圆
Matplotlib从入门到精通03-布局格式定方圆
Matplotlib从入门到精通03-布局格式定方圆
|
4月前
|
前端开发 API Python
Matplotlib从入门到精通02-层次元素和容器
Matplotlib从入门到精通02-层次元素和容器
Matplotlib从入门到精通02-层次元素和容器
|
4月前
|
机器学习/深度学习 数据可视化 API
Matplotlib从入门到精通01-matplotlib简介与绘图基本流程
Matplotlib从入门到精通01-matplotlib简介与绘图基本流程
Matplotlib从入门到精通01-matplotlib简介与绘图基本流程
|
6月前
|
Python Windows
Python Matplotlib入门
Matplotlib_Study01 极坐标 雷达图代码:# 标签labels = np.array(['艺术A', '调研I', '实际R', '常规C', '企业E', '社会S'])# 数据个数dataLenth = 6# 数据data = np.array([1, 4, 3, 6, 4, 8])# 生成从0开始到6.28的6个并且不可能包括6.28 的一个数组# 这里又将原数组赋给...
71 0