Task 04:文字图例尽眉目


前言

通过之前三个任务的学习,本次的主要任务是对于文字、图例的学习,主要讲解了如何设置Figure和Axes上的文本、Tick上的文本、图例等内容。


一、Figure和Axes上的文本

Matplotlib具有广泛的文本支持,包括对数学表达式的支持、对栅格和矢量输出的TrueType支持、对任意旋转的换行分隔文本以及Unicode支持。
下面的命令通过pyplot API和objected-oriented API分别创建文本。
在这里插入图片描述

1.text

pyplot API:matplotlib.pyplot.text(x, y, s, fontdict=None, **kwargs)
OO API:Axes.text(self, x, y, s, fontdict=None, **kwargs)

参数:
s:要添加的文本;
xy:放置文本的点(x,y);
fontdict:此参数是一个可选参数,并且是一个覆盖默认文本属性的字典。如果fontdict为None,则由rcParams确定默认值。

返回值:返回作为创建的文本实例的文本。

fontdict具体参数介绍请参考https://matplotlib.org/stable/api/text_api.html

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.font_manager import FontProperties 
#fontdict学习案例 
#学习的过程中请尝试更换不同的fontdict字典的内容,以便于更好的掌握 
#---------设置字体样式,分别是字体,颜色,宽度,大小 
font1 = {'family': 'SimSun',#华文楷体 
         'alpha':0.7,#透明度 
         'color': 'purple', 
         'weight': 'normal', 
         'size': 16, } 
font2 = {'family': 'Times New Roman', 
         'color': 'red', 
         'weight': 'normal', 
         'size': 16, } 
font3 = {'family': 'serif', 
         'color': 'blue', 
         'weight': 'bold', 
         'size': 14, } 
font4 = {'family': 'Calibri', 
         'color': 'navy', 
         'weight': 'normal', 
         'size': 17, } 
#-----------四种不同字体显示风格----- 
#-------建立函数---------- 
x = np.linspace(0.0, 5.0, 100) 
y = np.cos(2*np.pi*x) * np.exp(-x/3) 
#-------绘制图像,添加标注---------- 
plt.plot(x, y, '--') 
plt.title('震荡曲线', fontdict=font1) 
#------添加文本在指定的坐标处------------ 
plt.text(2, 0.65, r'$\cos(2 \pi x) \exp(-x/3)$', fontdict=font2) 
#---------设置坐标标签 
plt.xlabel('Y=time (s)', fontdict=font3) 
plt.ylabel('X=voltage(mv)', fontdict=font4) 
# 调整图像边距 
plt.subplots_adjust(left=0.15) 
plt.show()

在这里插入图片描述

2.title和set_title

pyplot API:matplotlib.pyplot.title(label, fontdict=None, loc=None, pad=None, *, y=None, **kwargs)
OO API:Axes.set_title(self, label, fontdict=None, loc=None, pad=None, *, y=None, **kwargs)

该命令是用来设置axes的标题。
参数
label:str,要添加的文本内容;
fontdict:dict,控制title文本的外观,默认fontdict如下:

{'fontsize': rcParams['axes.titlesize'], 'fontweight': rcParams['axes.titleweight'], 'color': rcParams['axes.titlecolor'], 'verticalalignment': 'baseline', 'horizontalalignment': loc}

loc:str,{‘center’, ‘left’, ‘right’}默认为center;
pad:float,标题偏离图表顶部的距离,默认为6;
y:float,title所在axes垂向的位置。默认值为1,即title位于axes的顶部;
kwargs:奇特文本的属性。

返回值:返回作为创建的title实例的文本。

3.figtext和text

pyplot API:matplotlib.pyplot.figtext(x, y, s, fontdict=None, **kwargs)
OO API:text(self, x, y, s, fontdict=None,**kwargs)

参数
x,y:float,在figure中放置文本的位置。一般取值是在[0,1]范围内。使用transform关键字可以更改坐标系;
s:str,文本内容;
fontdict:dict,此参数是一个可选参数,并且是一个覆盖默认文本属性的字典。如果fontdict为None,则由rcParams确定默认值。

返回值:返回作为创建的文本实例的文本。

4.suptitle

pyplot API:matplotlib.pyplot.suptitle(t, **kwargs)
OO API:suptitle(self, t, **kwargs)

参数
t: str,标题的文本;
x:float,默认值是0.5.文本在figure坐标系下的x坐标;
y:float,默认值是0.95.文本在figure坐标系下的y坐标;
horizontalalignment, ha:文本水平对齐方式,有三种选择{‘center’, ‘left’, right’},默认值是 ‘center’;
verticalalignment, va:文本垂直对齐方式,有四种选择{‘top’, ‘center’, ‘bottom’, ‘baseline’},默认值是 ‘top’;
fontsize, size:文本的大小,默认值是依据rcParams的设置:rcParams[“figure.titlesize”] (default:‘large’);
fontweight, weight:设置字重。默认值是依据rcParams的设置:rcParams[“figure.titleweight”] (default: ‘normal’);
fontproperties:None or dict,该参数是可选参数,如果该参数被指定,字体的大小将从该参数的默认值中提取。

返回值:返回作为创建的title实例的文本。

5.xlabel和ylabel

pyplot API:matplotlib.pyplot.xlabel(xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)
            matplotlib.pyplot.ylabel(ylabel, fontdict=None, labelpad=None,*, loc=None, **kwargs)
OO API:  Axes.set_xlabel(self, xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)
         Axes.set_ylabel(self, ylabel, fontdict=None, labelpad=None,*, loc=None, **kwargs)

参数
xlabel或者ylabel:label的文本;
labelpad:设置label距离轴(axis)的距离;
loc:{‘left’, ‘center’, ‘right’},默认为center;
**kwargs:文本属性。

返回值:返回作为创建的xlabel和ylabel实例的文本。

#文本属性的输入一种是通过**kwargs属性这种方式,一种是通过操作 matplotlib.font_manager.FontProperties 方法 
#该案例中对于x_label采用**kwargs调整字体属性,y_label则采用 matplotlib.font_manager.FontProperties 方法调整字体属性 
#该链接是FontProperties方法的介绍 https://matplotlib.org/api/font_manager_api.html
#matplotlib.font_manager.FontProperties 
x1 = np.linspace(0.0, 5.0, 100) 
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1) 
font = FontProperties() 
font.set_family('serif') 
font.set_name('Times New Roman') 
font.set_style('italic') 
fig, ax = plt.subplots(figsize=(5, 3)) 
fig.subplots_adjust(bottom=0.15, left=0.2) 
ax.plot(x1, y1) 
ax.set_xlabel('time [s]', fontsize='large', fontweight='bold') 
ax.set_ylabel('Damped oscillation [V]', fontproperties=font) 
plt.show()

在这里插入图片描述

6.字体的属性设置

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

#首先可以查看matplotlib所有可用的字体 
from matplotlib import font_manager 
font_family = font_manager.fontManager.ttflist 
font_name_list = [i.name for i in font_family] 
for font in font_name_list[:10]: 
    print(f'{font}\n')

在这里插入图片描述

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

在这里插入图片描述

#局部字体的修改方法2 
import matplotlib.pyplot as plt 
import matplotlib.font_manager as fontmg 
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
plt.plot(x, label='小示例图标签') 
#fname为你系统中的字体库路径 
my_font1 = fontmg.FontProperties(fname=r'C:\Windows\Fonts\simhei.ttf') # 读取系统中的黑体字体。 
my_font2 = fontmg.FontProperties(fname=r'C:\Windows\Fonts\simkai.ttf') # 读取系统中的楷体字体。
# fontproperties设置中文显示,fontsize设置字体大小 
plt.xlabel('x 轴名称参数', fontproperties=my_font1, fontsize=16) # 设置x轴名称 
plt.ylabel('y 轴名称参数', fontproperties=my_font1, fontsize=14) # 设置Y轴名称 
plt.title('坐标系的标题', fontproperties=my_font2, fontsize=20) # 标题的字体设置 
plt.legend(loc='lower right', prop=my_font1, fontsize=10); # 小示例图的字体设置

在这里插入图片描述

7.数学表达式

在文本标签中使用数学表达式。有关MathText的概述,请参见https://matplotlib.org/stable/tutorials/text/mathtext.html,下面是一个官方案例,供参考了解。

import numpy as np 
import matplotlib.pyplot as plt 
t = np.arange(0.0, 2.0, 0.01) 
s = np.sin(2*np.pi*t) 
plt.plot(t, s) 
plt.title(r'$\alpha_i > \beta_i$', fontsize=20) 
plt.text(1, -0.6, r'$\sum_{i=0}^\infty x_i$', fontsize=20) 
plt.text(0.6, 0.6, r'$\mathcal{A}\mathrm{sin}(2 \omega t)$', fontsize=20) 
plt.xlabel('time (s)') 
plt.ylabel('volts (mV)') 
plt.show()

在这里插入图片描述

总结案例

import matplotlib 
import matplotlib.pyplot as plt 
fig = plt.figure() 
ax = fig.add_subplot(111) 
fig.subplots_adjust(top=0.85) 
# 分别在figure和subplot上设置title 
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold') 
ax.set_title('axes title') 
ax.set_xlabel('xlabel') 
ax.set_ylabel('ylabel') 
# 设置x-axis和y-axis的范围都是[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}) 
ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15) 
font1 = {'family': 'Times New Roman', 'color': 'purple', 'weight': 'normal', 'size': 10, } 
ax.text(3, 2, 'unicode: Institut für Festkörperphysik',fontdict=font1) 
ax.text(0.95, 0.01, 'colored text in axes coords', verticalalignment='bottom', horizontalalignment='right', transform=ax.transAxes, color='green', fontsize=15) 
plt.show()

在这里插入图片描述

二、Tick上的文本

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

1.简单模式

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

import matplotlib.pyplot as plt 
import numpy as np 
import matplotlib 
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()

在这里插入图片描述

# 使用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()

在这里插入图片描述

#一般绘图时会自动创建刻度,而如果通过使用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()

在这里插入图片描述

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()

在这里插入图片描述

# 接收函数的例子 
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()

在这里插入图片描述

b) Tick Locators

在普通的绘图中,我们可以直接通过上图的set_ticks进行设置刻度的位置,缺点是需要自己指定或者接受matplotlib默认给定的刻度。
当需要更改刻度的位置时,matplotlib给了几种常用的locator类型。
如果要绘制更复杂的图,可以先设置locator的类型,然后通过axs.xaxis.set_major_locator(locator)绘制即可。
locator=plt.MaxNLocator(nbins=7)
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个刻度

# 接收各种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=10) 
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()

在这里插入图片描述
此外matplotlib.dates 模块还提供了设置日期型刻度格式和位置的方式。

import matplotlib.dates as mdates 
import datetime 
# 特殊的日期型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()

在这里插入图片描述

进阶案例

#这个案例中展示了如何进行坐标轴的移动,如何更改刻度值的样式 
import matplotlib.pyplot as plt 
import numpy as np 
x = np.linspace(-3,3,50) 
y1 = 2*x+1 
y2 = x**2 
plt.figure() 
plt.plot(x,y2) 
plt.plot(x,y1,color='red',linewidth=1.0,linestyle = '--') 
plt.xlim((-3,5)) 
plt.ylim((-3,5)) 
plt.xlabel('x') 
plt.ylabel('y') 
new_ticks1 = np.linspace(-3,5,5) 
plt.xticks(new_ticks1) 
plt.yticks([-2,0,2,5],[r'$one\ shu$',r'$\alpha$',r'$three$',r'four']) 
''' 上一行代码是将y轴上的小标改成文字,其中,空格需要增加\,即'\ ',$可将格式更改成数字模式,如果需要输入数学形式的α,则需要用\转换,即\alpha 
如果使用面向对象的命令进行画图,那么下面两行代码可以实现与 plt.yticks([-2,0,2,5],[r'$one\ shu$',r'$\alpha$',r'$three$',r'four']) 同样的功能 
axs.set_yticks([-2,0,2,5]) axs.set_yticklabels([r'$one\ shu$',r'$\alpha$',r'$three$',r'four']) 
''' 
ax = plt.gca()#gca = 'get current axes' 获取现在的轴 
'''
ax = plt.gca()是获取当前的axes,其中gca代表的是get current axes。 
fig=plt.gcf是获取当前的figure,其中gcf代表的是get current figure。 
许多函数都是对当前的Figure或Axes对象进行处理, 例如plt.plot()实际上会通过plt.gca()获得当前的Axes对象ax,
然后再调用ax.plot()方法实现真正的绘图。 而在本例中则可以通过ax.spines方法获得当前顶部和右边的轴并将其颜色设置为不可见 
然后将左边轴和底部的轴所在的位置重新设置 最后再通过set_ticks_position方法设置ticks在x轴或y轴的位置,
本示例中因所设置的bottom和left是ticks在x 轴或y轴的默认值,所以这两行的代码也可以不写 ''' 
ax.spines['top'].set_color('none') 
ax.spines['right'].set_color('none') 
ax.spines['left'].set_position(('data',0)) 
ax.spines['bottom'].set_position(('data',0))#axes 百分比 
ax.xaxis.set_ticks_position('bottom') #设置ticks在x轴的位置 
ax.yaxis.set_ticks_position('left') #设置ticks在y轴的位置 
plt.show()

在这里插入图片描述

三、legend(图例)

使用图例时会有一些常见术语,为了清楚起见,这些术语在此处进行说明: ** legend entry(图例条目)**
图例有一个或多个legend entries组成。
一个entry由一个key和一个label组成。
** legend key(图例键): 每个legend label左面的colored/patterned marker(彩色/图案标记) 。
** legend label(图例标签)
:由key来表示的handle的文本 。
** legend handle(图例句柄)**: 在图例中生成适当图例条目的原始对象。

常用参数:
(1)设置图例位置
plt.legend(loc=‘upper center’) 等同于plt.legend(loc=9),对应关系表之前讲过,不再赘述。
(2)设置图例字体大小
fontsize : int or float or {‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’}
(3)设置图例边框及背景
plt.legend(loc=‘best’,frameon=False) #去掉图例边框
plt.legend(loc=‘best’,edgecolor=‘blue’) #设置图例边框颜色
plt.legend(loc=‘best’,facecolor=‘blue’) #设置图例背景颜色,若无边框,参数无效
(4)设置图例标题
legend = plt.legend([“CH”, “US”], title=‘China VS Us’)
(5)设置图例名字及对应关系
legend = plt.legend([p1, p2], [“CH”, “US”])

line_up, = plt.plot([1, 2, 3], label='Line 2') 
line_down, = plt.plot([3, 2, 1], label='Line 1') 
plt.legend([line_up, line_down], ['Line Up', 'Line Down'],loc=5, title='line',frameon=False);#loc参数设置图例所在的位置,title设置图例的标题,frameon参数将图例边框去掉

在这里插入图片描述

#这个案例是显示多图例legend 
import matplotlib.pyplot as plt 
import numpy as np 
x = np.random.uniform(-1, 1, 4) 
y = np.random.uniform(-1, 1, 4) 
p1, = plt.plot([1,2,3]) 
p2, = plt.plot([3,2,1]) 
l1 = plt.legend([p2, p1], ["line 2", "line 1"], loc='upper left') 
p3 = plt.scatter(x[0:2], y[0:2], marker = 'D', color='r') 
p4 = plt.scatter(x[2:], y[2:], marker = 'D', color='g') 
# 下面这行代码由于添加了新的legend,所以会将l1从legend中给移除 
plt.legend([p3, p4], ['label', 'label1'], loc='lower right', scatterpoints=1) 
# 为了保留之前的l1这个legend,所以必须要通过plt.gca()获得当前的axes,然后将l1作为单独的artist 
plt.gca().add_artist(l1);

在这里插入图片描述

总结

以上就是今天要讲的内容,本文介绍了在Figure和Axes上的文字,其中包括对text、title、字体属性等的设置,和Tick文本设置以及图例等内容。

参考资料

[1].https://matplotlib.org/stable/tutorials/text/text_intro.html#sphx-glr-tutorials-text-text-intro-py

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Never give up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值