文章目录
- 自定义坐标刻度
- 编程要求
- 代码解释
自定义坐标刻度
虽然matplotlib默认的坐标轴定位器与格式生成器可以满足大部分需求,但是并非对每一幅图都合适。
主次要刻度
学习前最好先对matplotlib图形的对象层级有深入了解。
matplotlib的figure对象是一个盛放图形元素的包围盒。可以将每个matplotlib对象都看成是子对象的容器,每个figure都包含axes对象,每个axes对象又包含其他表示图形内容的对象,比如xaxis/yaxis,每个属性包含构成坐标轴的线条、刻度和标签的全部属性。
每一个坐标轴都有主次要刻度,主要刻度要比次要刻度更大更显著,而次要刻度往往更小。
import matplotlib.pyplot as plt
import numpy as np
ax = plt.axes(xscale='log', yscale='log')
plt.show()
可以看到主要刻度都显示为一个较大的刻度线和标签,而次要刻度都显示为一个较小的可读性,不显示标签。
隐藏刻度与标签
最常用的刻度/标签格式化操作可能就是隐藏刻度与标签了,可以通过plt.NullLocator()和plt.NullFormatter()实现。
示例如下:
ax = plt.axes()
ax.plot(np.random.rand(50))
ax.yaxis.set_major_locator(plt.NullLocator())
ax.xaxis.set_major_formatter(plt.NullFormatter())
plt.show()
这里x轴的标签隐藏了但是保留了刻度线,y轴的刻度和标签都隐藏了。有的图片中都不需要刻度线,比如下面这张包含人脸的图形:
fig, ax = plt.subplots(5, 5, figsize=(5, 5))
fig.subplots_adjust(hspace=0, wspace=0)
从scikit-learn获取一些人脸照片数据
from sklearn.datasets import fetch_olivetti_faces
faces = fetch_olivetti_faces().images
for i in range(5):for j in range(5):ax[i, j].xaxis.set_major_locator(plt.NullLocator())ax[i, j].yaxis.set_major_locator(plt.NullLocator())ax[i, j].imshow(faces[10 * i + j], cmap="bone")
plt.show()
花哨的刻度格式
matplotlib默认的刻度格式可以满足大部分的需求。虽然默认配置已经很不错了,但是有时候可能需要更多的功能,比如正弦曲线和余弦曲线。
默认情况下刻度为整数,如果将刻度与网格线画在π的倍数上图形会更加自然,可以通过设置一个multipleLocator来实现将刻度放在你提供的数值倍数上:
fig, ax = plt.subplots()
x = np.linspace(0, 3 * np.pi, 1000)
ax.plot(x, np.sin(x), lw=3, label='Sine')
ax.plot(x, np.cos(x), lw=3, label='Cosine')
设置网格、图例和坐标轴上下限
ax.grid(True)
ax.legend(frameon=False)
ax.axis('equal')
ax.set_xlim(0, 3 * np.pi)
ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2))
ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4))
plt.show()
matplotlib还支持用数学符号来做刻度,在数学表达式两侧加上美元符号$,这样就可以方便地显示数学符号和数学公式。
可以用plt.FuncFormatter来实现,用一个自定义函数设置不同刻度标签的显示:
def format_func(value, tick_number):
找到π/2的倍数刻度
N = int(np.round(2 * value / np.pi))if N == 0:return "0"elif N == 1:return r"$\pi/2$"elif N == 2:return r"$\pi$"elif N % 2 > 0:return r"${0}\pi/2$".format(N)else:return r"${0}\pi$".format(N // 2)
ax.xaxis.set_major_formatter(plt.FuncFormatter(format_func))
格式生成器与定位器
前面已经介绍了一些格式生成器和定位器,这里再用表格简单总结一些内置的格式生成器和定位器:
定位器 描述
NullLocator 无刻度
FixedLocator 刻度位置固定
IndexLocator 用索引作为定位器
LinearLocator 从min到max均匀分布刻度
LogLocator 从min 到max按对数分布刻度
MultipleLocator 刻度和范围都是基数的倍数
MaxNLocator 为最大刻度找到最优位置
AutoMinorLocator 次要刻度的定位器
格式生成器 描述
NullFormatter 刻度上无标签
IndexFormatter 将一组标签设置为字符串
FixedFormatter 手动为刻度设置标签
FuncFormatter 用自定义函数设置标签
FormatStrFormatter 为每个刻度值设置字符串格式
ScalarFormatter 为标量值设置标签
LogFormatter 对数坐标轴的默认格式生成器
编程要求
在右侧编辑器补充代码,根据file_path读取文件,统计不同二级类的数量做折线图并旋转x坐标轴90度,具体要求如下:
图形的figsize为(10, 10);
图形需保存到Task3/img/T1.png。
数据内容如下:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif']=['simhei']
plt.rcParams['font.family']='sans-serif'
plt.rcParams['axes.unicode_minus']=Falsedef student(file_path):# ********* Begin *********#plt.figure(figsize=(10,10))data=pd.read_csv(file_path)a=data.groupby(["二级类"])["二级类"].count()plt.plot(a)plt.xticks(rotation=90)plt.savefig("Task3/img/T1.png")plt.show()# ********* End *********#
代码解释
创建图形对象并设置大小:
plt.figure(figsize=(10,10))
这行代码初始化一个图形窗口,并设置其大小为10x10英寸。
读取CSV文件:
data=pd.read_csv(file_path)
使用pandas库的read_csv函数读取file_path指定的CSV文件,并将数据存储在data变量中。注意,这里变量名由file_name更改为file_path,这表示传入的参数应该是一个文件路径字符串。
数据分组统计:
a=data.groupby(["二级类"])["二级类"].count()
使用pandas的groupby函数对data中的数据按照“二级类”列进行分组,然后使用count函数计算每个“二级类”分组中的行数(即每个类别的数量)。结果存储在a变量中,这是一个Series对象,索引是“二级类”的唯一值,值是对应的计数。
绘制折线图:
plt.plot(a)
使用matplotlib的plot函数绘制a的折线图。由于a是一个Series对象,它的索引(即“二级类”的唯一值)将作为x轴的值,它的值(即每个类别的数量)将作为y轴的值。
设置x轴刻度标签的旋转角度:
plt.xticks(rotation=90)
这行代码设置x轴刻度标签的旋转角度为90度,通常用于当x轴标签较长或较多时,避免它们之间的重叠,使图表更易读。
保存图表:
plt.savefig("Task3/img/T1.png")
使用savefig函数将当前绘制的图表保存为PNG格式的图像文件,文件名为T1.png,保存在Task3/img/目录下。如果目录不存在,代码将会抛出异常。
显示图表:
plt.show()
最后,使用show函数在屏幕上显示图表。如果代码运行在一个支持图形用户界面的环境中,这将会弹出一个窗口来显示图表。