matplotlib API函数(如plot和close)都位于matplotlib.pyplot模块中,通常的引入约定为:
import matplotlib.pyplot as plt
绘制一张简单的图表检测是否一切就绪:
plt.plot(np.arange(10)) 在jupyter notebook中不需要plt.show()
plt.plot(np.arange(10))
设置标题 ----------- plt.title(AAPL stock price change)
设置图例 ----------- plt.plot(x, y, label=AAPL) plt.legend()
设置坐标轴标签 ----------- plt.xlabel(time) plt.ylabel(stock price)
设置坐标轴范围 ----------- plt.ylim(0,500) plt.xlim(datetime(1990,2,1),datetime(2015,2,1))
设置图像大小 ----------- plt.figure(figsize=[6,6])
设置(箭头)标注 ----------- plt.annotate
添加文字 ----------- plt.text() / AxesSubplot.text()
设置标题
设置坐标轴标签
如果要设置的坐标轴标签是中文,还需要在plt.xlabel()/plt.ylabel()中设置fontproperties
设置坐标轴范围
设置图例
末尾需要加上plt.legend()显示图例
设置图像大小
设置箭头标注
这里稍微讲解一下plt.annotate()方法的参数
annotate(*args, **kwargs) Annotate the point ``xy`` with text ``s``.
Additional kwargs are passed to `~matplotlib.text.Text`.
s : str The text of the annotation,注释字元串
xy : iterable Length 2 sequence specifying the *(x,y)* point to annotate,注释目标点的坐标
xytext : iterable, optional Length 2 sequence specifying the *(x,y)* to place the text at. If None, defaults to ``xy``.注释字元串的坐标
xycoords : str, Artist, Transform, callable or tuple, optional The coordinate system that ``xy`` is given in. 目标点坐标所在的坐标系统,默认为data,即被注释对象所在的坐标系统。
textcoords : str, `Artist`, `Transform`, callable or tuple, optional The coordinate system that ``xytext`` is given, which may be different than the coordinate system used for ``xy``. 注释字元串的坐标所在的坐标系统,默认与xycoords相同, 也可以设置为offset points或offset pixels这种偏移量的形式
================= ========================================= Property Description ================= ========================================= offset points offset (in points) from the *xy* value offset pixels offset (in pixels) from the *xy* value ================= =========================================
arrowprops : dict, optional If not None, properties used to draw a `~matplotlib.patches.FancyArrowPatch` arrow between ``xy`` and ``xytext``. 常用的键是arrowstyle和connectionstyle
The allowed values of ``arrowstyle`` are: ============ ============================================= Name Attrs ============ ============================================= ``-`` None ``->`` head_length=0.4,head_width_=0.2 ``-[`` widthB=1.0,lengthB=0.2,angleB=None ``|-|`` widthA=1.0,widthB=1.0 ``-|>`` head_length=0.4,head_width_=0.2 ``<-`` head_length=0.4,head_width_=0.2 ``<->`` head_length=0.4,head_width_=0.2 ``<|-`` head_length=0.4,head_width_=0.2 ``<|-|>`` head_length=0.4,head_width_=0.2 ``fancy`` head_length=0.4,head_width_=0.4,tail_width_=0.4 ``simple`` head_length=0.5,head_width_=0.5,tail_width_=0.2 ``wedge`` tail_width_=0.3,shrink_factor=0.5 ============ =============================================
connectionstyle设置见下图
重点参数: s 注释字元串 xy 注释目标点的坐标 xytext 注释字元串的坐标 arrowprops 各种connectionstyle:不同的angle(角度)和rad(弧度)
下面调一下connectionstyle
把textcoords设为偏移量的形式:
添加文本
同一个数据坐标系中,在(x,y)坐标处添加文本。调用可以用plt.text() 或 AxesSubplot.text()
重点参数: x, y s
text()方法中除x, y, s之外较常用的参数有fontsize、va和ha,ha是HorizontalAlignment的简写,ha=center即水平对齐,除此之外还可以选择left(左对齐)或right(右对齐); va则是VerticalAlignment的简写,va可以选择[ center | top | bottom | baseline ]中的任何一个,意思分别为垂直居中、顶端居中、底端居中和底线居中
plot(x,y,color=,marker=,linestylex=)
matplotlib的plot函数接受一组X和Y坐标,还可以通过color、marker和linestyle关键字传入指定的颜色、标记和线型,或者用一个表示颜色、标记和线型的格式字元串替代,两种方法是等效的。格式字元串中color、marker和linestyle的位置任意,如ko--,k--o,o--k
如果要根据x和y绘制绿色虚线,可以执行如下代码:
也可以通过关键字显式指定:
常用的颜色都有一个缩写词,如:
============= =============================== character color ============= =============================== ``b`` blue ``g`` green ``r`` red ``c`` cyan ``m`` magenta ``y`` yellow ``k`` black ``w`` white ============= ===============================
详细的corlor如下
要使用其他颜色任意颜色可以指定特定颜色的16进位颜色码,如#998301。
需要注意的是不要因为我把color、marker和linestyle放在一起介绍而误以为它们是一起出现的,三者中color是最常单独出现的。
线形图还可以加上一些标记(marker),以强调实际的数据点。由于matplotlib创建的是连续的线形图(点与点之间插值),因此有时候不太容易看出真实数据点的位置。标记也可以放到格式字元串中。
和上面的方法等效:
在线型图中,非实际数据点默认是按线性方式插值的,可以通过drawstyle选项修改:
drawstyle: [default | steps | steps-pre | steps-mid | steps-post]
不过这个关键字你大概用不到
再讲style,matplotlib的style setting有如下几种,用plt.style.use(ggplot)形式使用
如
具体的效果见:
matplotlib的图像都位于Figure对象中,但不能直接通过Figure绘图。必须创建一个或多个subplot(子图)才行。
i)plt.subplots创建子图
由于根据特定布局创建Figure和subplot是一件非常常见的任务,于是便出现了一个更为方便的方法——plt.subplots,它可以创建一个新的Figure,并返回一个含有已创建的AxesSubplot对象的NumPy数组。
这是非常实用的,因为可以轻松地对axes数组进行索引,就好像是一个二维数组一样,例如axes[0,1],直接调用这些AxesSubplot对象的实例方法就可以在空白子图里画图了。
还有一点需要注意的是,在DataFrame和Series上直接画图返回的也是一个AxesSubplot对象
而用plt.plot(x,y)这种形式返回的是列表类型
BTW:cumsum是累和,cumprod是累积。举两个例子:
pyplot.subplots参数说明:
subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, gridspec_kw=None, **fig_kw)
参数 说明 nrows subplot的行数 ncols subplot的列数 sharex 所有subplot使用相同的X轴刻度(调节xlim将会影响所有subplot) sharey 所有subplot使用相同的Y轴刻度(调节ylim将会影响所有subplot)
ii)plt.subplot创建子图
pyplot.subplot参数说明:
subplot(nrows, ncols, index, **kwargs)
iii)调整suplot周围的间距————subplots_adjust
默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关,因此,如果你调整了图像大小(不管是编程还是手工),间距也会自动调整。利用Figure的subplots_adjust方法可以轻而易举地修改间距,此外,它也是一个顶级函数。
AxesSubplot.set_title() #设置标题
AxesSubplot.set_xlabel() #设置轴标签 AxesSubplot.set_ylabel()
AxesSubplot.set_xticks() #设置刻度 (横坐标等于哪些值的时候显示刻度) AxesSubplot.set_yticks()
AxesSubplot.set_xticklabels() #设置刻度标签 (刻度之下显示什么,默认是其代表的值) AxesSubplot.set_yticklabels()
上面四种都是AxesSubplot对象的实例方法,请注意。
基本plot:
设置刻度:
设置刻度和刻度标签:
设置刻度、刻度标签、标题和轴标签:
添加图例最简单的方式是在AxesSubplot对象上绘图的时候传入label参数,在此之后,你可以选择AxesSubplot.legend()或plt.legend()来显示图例
不难看出,matplotlib实际上是一种比较低级的工具。要组装一张图表,你得用它的各种基础组件才行:
这是因为要根据数据制作一张完整的图表通常都需要用到多个对象。在pandas中,我们有行标签、列标签以及分组信息(可能有)。这也就是说,要制作一张完整的图表,原本需要一大堆的matplotlib代码,现在只需要一两条简洁的语句就可以了。pandas有许多能够利用DataFrame对象数据组织特点来创建图表的高级绘图方法。
Series.plot方法的参数:
__call__(self, kind=line, ax=None, figsize=None, use_index=True, title=None, grid=None, legend=False, stylex=None, logx=False, logy=False, loglog=False, xticks=None, yticks=None, xlim=None, ylim=None, rot=None, fontsize=None, colormap=None, table=False, yerr=None, xerr=None, label=None, secondary_y=False, **kwds)
参数 说明
kind 图表类型可以是line、bar、barh、kde等 | - line : line plot (default) | - bar : vertical bar plot | - barh : horizontal bar plot | - hist : histogram | - box : boxplot | - kde : Kernel Density Estimation plot | - density : same as kde | - area : area plot | - pie : pie plot | - scatter : scatter plot | - hexbin : hexbin plot
ax 要在其上进行绘制的matplotlib subplot对象。如果没有设置, 则使用当前的matplotlib subplot
figsize 设置图像大小
fontsize int, default None 轴标签、注释等的字体大小
use_index 将对象的索引用作刻度标签
title 设置图表标题
label 用于图例的标签
style 要传给matplotlib的风格字元串(也可以通过color、marker、linstyle关键字分别传入)
alpha 图表的填充不透明度(0到1之间)
logy 在Y轴上使用对数标尺
rot 旋转刻度标签(0到360)
xticks 用作X轴刻度的值, list类型
yticks 用作Y轴刻度的值, list类型
xlim X轴的界限,如[0,10]
ylim Y轴的界限
grid 显示轴网格线(默认打开)
重点参数: kind ax title label figsize
i)线形图
1)Series画图
Series和DataFrame都有一个用于生成各类图表的plot方法。默认情况下,它们生成的都是线形图。
该Series对象的索引会被传给matplotlib,并用以绘制X轴。可以通过use_index=False禁用改功能。X轴的刻度和界限可以通过xticks和xlim选项进行调节,Y轴就用yticks和ylim。pandas的大部分绘图方法都有一个可选的ax参数,它可以是一个matplotlib的AxesSubplot对象。这让你能够在网格布局中更为灵活地处理subplot的位置。
2)DataFrame画图
DataFrame的plot方法会在一个subplot中为各列绘制一条线,并自动创建图例:
DataFrame还有一些用于对列进行灵活处理的选项,例如,是要将所有列都绘制到一个subplot中还是创建各自的subplot:
专用于DataFrame的plot参数:
参数 说明 subplots 将各个DataFrame列绘制到单独的subplot中
sharex 如果subplots=True,则公用一个X轴,包括刻度和界限
sharey 如果subplots=True,则公用一个Y轴
figsize 表示图像大小的元组
title 表示图像标题的字元串
legend 添加一个subplot图例,默认为True
sort_columns 以字元表顺序绘制各列,默认使用当前的顺序
有时我们还会遇到要将DataFrame的不同的多个列绘制到不同子图上的情形(different subsets of the columns),下面给出一个实际应用的示例:
原始数据如下
代码如下
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns
path = r"C:UsersyqpzDesktop现货策略买入点调试5-511.19.csv"
df = pd.read_csv(path,engine=python, encoding=utf_8_sig, usecols=[0,1,2,3,4,5,6], index_col=0,parse_dates=True)
sns.set(stylex=whitegrid) fig, axes = plt.subplots(2,1) df[df.columns[:4]].plot(ax=axes[0], figsize=[12,9]) df[df.columns[4:]].plot(ax=axes[1])
plt.show()
这里还有一点需要稍微注意下:如果你用df.plot()的形式,那么图例会使用column names并自动显示(不需要加plt.legend()),但如果你使用的是s.plot(),如df.close.plot()这种形式,series.name不会自动作为图例显示。
加ticks效果很特别
import seaborn as sns import matplotlib.pyplot as plt from 量化.data_processing.single_pair_processing import single_pair_processing
path = r"C:UsersyqpzPycharmProjectsNumPy & Pandas量化data1min_btcusdt_kline3月2日.txt" df = single_pair_processing(path)
points = [2019-03-02 01:44, 2019/3/2 2:19, 2019-03-02 02:51, 2019-03-02 05:47, 2019-03-02 05:49,2019-03-02 06:32]
sns.set(style=whitegrid) fig, axes= plt.subplots(2,1) df[[close]].plot(ax=axes[0], xticks=points) df[[volume]].plot(ax=axes[1]) plt.show()
在生成线形图的代码中加上kind=bar(垂直柱状图)或kind=barh(水平柱状图)即可生成柱状图。
1)Series绘图
Series的索引将会被用作X(bar)轴或Y轴(barh)刻度
2)DataFrame绘图
对于DataFrame,柱状图会将每一行的值分为一组。
注意:DataFrame各列的名称Genus被用作了图例的标题
设置stacked=True即可为DataFrame生成堆积柱状图,这样每行的值就会被堆积在一起:
再以之前用过的小费数据集为例,假设我们想要做一张堆积柱状图以展示每天各种聚会规模的数据点的百分比
先用read_csv将数据载入进来,然后根据日期和聚会规模创建一张交叉表:
然后进行规格化,使得各行的和为1,并生成图表:
如果想给每个柱形加上对应的数字该怎么做?
在这里ax.patches 返回的是一个Rectangle对象的列表, 而Rectangle对象有如下四种方法:
get_x() 返回矩形左侧的x轴坐标 get_y() 返回矩形底部的y轴坐标 get_height() 返回矩形的高度 get_width() 返回矩形的宽度
直方图
直方图(histogram)是一种可以对值频率进行离散化显示的柱状图。数据点被拆分到离散的、间隔均匀的面元中,绘制的是各面元中数据点的数量。
再以前面的小费数据集为例,通过Series的hist方法,我们可以生成一张「小费占消费总额的百分比「的直方图:
当然,更推荐的做法还是下面这种:
对应的加xticks的两种方法,依旧更推荐后一种:
为DataFrame各(数值)列绘制直方图
核密度图
与直方图相关的另一种图表类型是核密度图,它是通过计算」观测数据的连续概率分布的估计「而产生的。一般的过程是将该分布近似为一组核(即诸如正态(高斯)分布之类的较为简单的分布)。因此,核密度图也被称为KDE(Kernel Density Estimate,核密度估计)图。调用plot时加上kind=kde即可生成一张密度图(标准混合正态分布KDE),如下图所示:
这两种图表常常会被画在一起。直方图以规格化的形式给出(以便给出面元化密度),然后再在其上绘制核密度估计。接下来来看一个由两个不同的标准正态分布组成的双峰分布:
散点图
散点图(scatter plot)是观察两个一维数组序列之间的关系的有效手段。matplotlib的scatter方法是绘制散点图的主要方法。
在下面这个例子中,载入了来自statsmodels项目的macrodata数据集,选择其中的几列,然后计算对数差。
或者用plot(kind=scatter)
给一个酷炫一点的示例:
path = r"C:UsersyqpzDesktophousing.csv"
housing = pd.read_csv(path, engine=python)
sns.set(stylex=white) housing.plot(kind=scatter, x=longitude, y=latitude, alpha=0.4, s=housing.population/100, label=population, c=median_house_value, cmap=plt.get_cmap(rainbow), colorbar=True) plt.show()
colormap可以在这上面找:
散点图矩阵
在探索式数据分析工作中,同时观察一组变数的散点图是很有意思的,这也被称为散点矩阵(scatter plot matrix)。纯手工创建这样的图表很费功夫,所以pandas提供了一个能从DataFrame创建散点图矩阵的scatter_matrix函数。它还支持在对角线上放置各变数的直方图或密度图。
Draw a matrix of scatter plots.
scatter_matrix(frame, alpha=0.5, figsize=None, ax=None, grid=False, diagonal=hist, marker=., density_kwds=None, hist_kwds=None, range_padding=0.05, **kwds)
frame : DataFrame
figsize : (float,float), optional a tuple (width, height) in inches
diagonal : {hist, kde} pick between kde and hist for either Kernel Density Estimation or Histogram plot in the diagonal
重点参数: frame diagonal figsize
for example:
制作帕累托图的关键是传入secondary_y=True
path = r"C:UsersyqpzDesktopDATA aw ips.csv"
df = pd.read_csv(path, engine=python, encoding=utf_8_sig)
day = df.groupby(day).size()
sns.set() day.plot(kind=pie, title=Number of parties on different days, figsize=[6,6], autopct=lambda p: {:.2f}%({:.0f}).format(p,(p/100)*day.sum())) plt.show()
这里需要注意的是autopct中lambda函数的p
p是指7.79、35.66、31.15和25.41,而不是百分比
换个配色
具体的colormap见这里:
也可以简单一点,只设置百分比
将图表保存到文件
利用plt.savefig可以将当前图表保存到指定位置,该方法相当于Figure对象的实例方法savefig
例如,要将图片保存为png,只需要输入:
plt.savefig(r"C:UsersyqpzDesktopplot.png")
文件类型是通过文件扩展名推断出来的。因此,如果你使用的是.pdf,就会得到一个PDF文件。在保存图片时最常用到的两个重要选项是dip(控制「每英寸点数」解析度)和bbox_inches(可以剪除当前图表周围的空白部分)。
要得到一张带有最小白边且解析度为400dpi的png图片,可以这样做:
或:
常见问题
Q1.标题无法设置成中文,どうして?
开头导入以下几行代码即可
import matplotlib as mpl mpl.rcParams[font.sans-serif]=[Microsoft YaHei] # 步骤一(替换sans-serif字体) mpl.rcParams[axes.unicode_minus]=False # 步骤二(解决坐标轴负数的负号显示问题
或
plt.rcParams[font.sans-serif] = [SimHei] plt.rcParams[axes.unicode_minus] = False