matplotlib API函數(如plot和close)都位於matplotlib.pyplot模塊中,通常的引入約定為:

import matplotlib.pyplot as plt

繪製一張簡單的圖表檢測是否一切就緒:

plt.plot(np.arange(10))

在jupyter notebook中不需要plt.show()

Figure畫圖

設置標題 ----------- 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設為偏移量的形式:

xytext=[50,30]表示標註位置相對於目標位置右移50,上移30;還可以通過fontsize設置標註的文字大小

添加文本

同一個數據坐標系中,在(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 ]中的任何一個,意思分別為垂直居中、頂端居中、底端居中和底線居中

顏色、圖表樣式、標記和線型————color、style、marker和linestyle

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如下

Visualizing named colors

要使用其他顏色任意顏色可以指定特定顏色的16進位顏色碼,如#998301。

需要注意的是不要因為我把color、marker和linestyle放在一起介紹而誤以為它們是一起出現的,三者中color是最常單獨出現的。

線形圖還可以加上一些標記(marker),以強調實際的數據點。由於matplotlib創建的是連續的線形圖(點與點之間插值),因此有時候不太容易看出真實數據點的位置。標記也可以放到格式字元串中。

和上面的方法等效:

dashed: (of a line on a piece of paper)composed of dashes

在線型圖中,非實際數據點默認是按線性方式插值的,可以通過drawstyle選項修改:

drawstyle: [default | steps | steps-pre | steps-mid | steps-post]

不過這個關鍵字你大概用不到

Style

再講style,matplotlib的style setting有如下幾種,用plt.style.use(ggplot)形式使用

具體的效果見:

Matplotlib Style Gallery?

tonysyu.github.io
圖標

Subplot畫圖

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()來顯示圖例


下面是重點

pandas中的繪圖函數

不難看出,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()

ii)柱形圖/條形圖

在生成線形圖的代碼中加上kind=bar(垂直柱狀圖)或kind=barh(水平柱狀圖)即可生成柱狀圖。

1)Series繪圖

Series的索引將會被用作X(bar)軸或Y軸(barh)刻度

2)DataFrame繪圖

對於DataFrame,柱狀圖會將每一行的值分為一組。

注意:DataFrame各列的名稱Genus被用作了圖例的標題

設置stacked=True即可為DataFrame生成堆積柱狀圖,這樣每行的值就會被堆積在一起:

再以之前用過的小費數據集為例,假設我們想要做一張堆積柱狀圖以展示每天各種聚會規模的數據點的百分比

先用read_csv將數據載入進來,然後根據日期和聚會規模創建一張交叉表:

1個人,5個人和6個人的聚會都比較少

然後進行規格化,使得各行的和為1,並生成圖表:

如果想給每個柱形加上對應的數字該怎麼做?

在這裡ax.patches 返回的是一個Rectangle對象的列表, 而Rectangle對象有如下四種方法:

get_x() 返回矩形左側的x軸坐標
get_y() 返回矩形底部的y軸坐標
get_height() 返回矩形的高度
get_width() 返回矩形的寬度

iii)直方圖和密度圖

直方圖

直方圖(histogram)是一種可以對值頻率進行離散化顯示的柱狀圖。數據點被拆分到離散的、間隔均勻的面元中,繪製的是各面元中數據點的數量。

再以前面的小費數據集為例,通過Series的hist方法,我們可以生成一張「小費佔消費總額的百分比「的直方圖:

當然,更推薦的做法還是下面這種:

對應的加xticks的兩種方法,依舊更推薦後一種:

預定訂單價格頻數分析

預定訂單價格頻數分析

為DataFrame各(數值)列繪製直方圖

核密度圖

與直方圖相關的另一種圖表類型是核密度圖,它是通過計算」觀測數據的連續概率分布的估計「而產生的。一般的過程是將該分布近似為一組核(即諸如正態(高斯)分布之類的較為簡單的分布)。因此,核密度圖也被稱為KDE(Kernel Density Estimate,核密度估計)圖。調用plot時加上kind=kde即可生成一張密度圖(標準混合正態分布KDE),如下圖所示:

這兩種圖表常常會被畫在一起。直方圖以規格化的形式給出(以便給出面元化密度),然後再在其上繪製核密度估計。接下來來看一個由兩個不同的標準正態分布組成的雙峰分布:

iv)散點圖(scatter)和散點圖矩陣(scatter matrix)

散點圖

散點圖(scatter plot)是觀察兩個一維數組序列之間的關係的有效手段。matplotlib的scatter方法是繪製散點圖的主要方法。

在下面這個例子中,載入了來自statsmodels項目的macrodata數據集,選擇其中的幾列,然後計算對數差。

或者用plot(kind=scatter)

給一個酷炫一點的示例:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

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可以在這上面找:

color example code: colormaps_reference.py?

matplotlib.org
圖標

散點圖矩陣

在探索式數據分析工作中,同時觀察一組變數的散點圖是很有意思的,這也被稱為散點矩陣(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:

v)帕累托(pareto)圖

製作帕累托圖的關鍵是傳入secondary_y=True

vi)餅圖(pie)

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

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見這裡:

Choosing Colormaps in Matplotlib?

matplotlib.org
圖標

也可以簡單一點,只設置百分比

將圖表保存到文件

利用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


推薦閱讀:
相关文章