matplotlib基本使用01
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
matplotlib 採用面嚮對象的技術來實現,因此組成圖表的各個元素都是對象,在編寫較大的應用程序的時候,通過面向對象的方式使用matplotlib講更加有效。但是使用這種面向對象的調用接口進行繪圖會比較繁瑣,因此matplotlib還提供了進行快速繪圖的pyplot模塊。同時爲了將matplotlib繪製的圖表嵌入到Notebook中,需要執行命令:%matplotlib inline
matplotlib-繪製精美的圖表
快速繪圖
%matplotlib inline
# 使用inline模式在Notebook中繪製的圖表會自動進行關閉,爲了在Notebook的多個單元格內操作同一幅圖表,需要運行下面的魔法命令:
%config InlineBackend.close_figures = False
使用pyplot模塊繪圖
matplotlib還提供了一個名爲pylab的模塊,其中包括了許多Numpy和pyplot模塊中常用的函數,方便用戶快速進行計算和繪圖,比較適合在IPython交互式環境中使用。
plt.plot?
#%fig=使用pyplot模塊快速將數據繪製成曲線圖
import matplotlib.pyplot as plt #❶
x = np.linspace(0, 10, 1000)
# print("x的值:{}".format(x))
y = np.sin(x)
# print("y的值:{}".format(y))
z = np.cos(x**2)
# print("z的值:{}".format(z))
plt.figure(figsize=(8,4)) #❷ 調用figure()創建一個Figure(圖表)對象,並且將它稱爲當前Figure對象。也可以不創建,直接條用plot()來進行繪圖。
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2) #❸ label該曲線指定一個標籤,用於在圖中顯示。如果標籤字符串的前後有字符"$",顯示爲Latex
plt.plot(x,z,"b--",label="$cos(x^2)$") #❹ 通過"b--"指定曲線的顏色和線型,b--藍色,--代表虛線。
plt.xlabel("Time(s)") #❺ 分別設置x,y軸的標題文字
plt.ylabel("Volt")
plt.title("PyPlot First Example") # 設置子圖的標題
plt.ylim(-1.2,1.2) # 分別設置x,y軸的顯示範圍
plt.legend() # 顯示圖示,即圖中表示每條曲線的標籤(label)和樣式的矩形區域。
plt.show() #❻ 調用plt.show()顯示繪圖窗口
plt.savefig("./t1.png", dpi = 120) # 將當前的Figure對象保存爲圖像文件,圖像格式由文件的拓展名決定。
WARNING
使用LaTeX語法繪製數學公式會極大地降低圖表的描繪速度。
plt.savefig("test.png", dpi=120)
<Figure size 432x288 with 0 Axes>
TIP
如果關閉了圖表窗口,則無法使用
savefig()
保存圖像。實際上不需要調用show()
顯示圖表,可以直接用savefig()
將圖表保存成圖像文件。使用這種方法可以很容易編寫批量輸出圖表的程序。
爲了更好的實現保存,要執行:%config InlineBackend.close_figures = False
import io
buf = io.BytesIO() # 創建一個用來保存圖像內容的BytesIO對象
plt.savefig(buf, fmt="png") # 將圖像以png格式保存進buf中
buf.getvalue()[:20] # 顯示圖像內容的前20個字節
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x02@'
面向對象方式繪圖
pyplot模塊的內部保存了當前圖表以及當前子圖等信息。可以使用gcf()和gca()獲得這兩個對象,“get current figure”“get current axes”
fig = plt.gcf()
axes = plt.gca()
print( fig, axes)
Figure(576x288) AxesSubplot(0.125,0.125;0.775x0.755)
配置屬性
#%fig[1x3]=配置繪圖對象的屬性
plt.figure(figsize=(4, 3))
x = np.arange(0, 5, 0.1)
print('x的值:{}'.format(x))
line = plt.plot(x, 0.05*x*x, "bo")[0] # plot返回一個列表
line.set_alpha(0.5) # 調用Line2D對象的set_*()方法設置屬性值,修改他在圖表中對應曲線的透明度
x的值:[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. 1.1 1.2 1.3 1.4 1.5 1.6 1.7
1.8 1.9 2. 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3. 3.1 3.2 3.3 3.4 3.5
3.6 3.7 3.8 3.9 4. 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9]
lines = plt.plot(x, np.sin(x), x, np.cos(x))
plt.setp(lines, color="r", linewidth=4.0) # 調用step()可以同時配置多個對象的屬性,這裏同時設置兩條曲線的顏色和線寬
[None, None, None, None]
print( line.get_linewidth())
print( plt.getp(lines[0], "color")) # 返回color屬性
1.5
r
# getp和setp不同,他只能對一個對象進行操作,可以指定屬性名或者不指定屬性名。
f = plt.gcf()
plt.getp(f)
agg_filter = None
alpha = None
animated = False
axes = [<matplotlib.axes._subplots.AxesSubplot object at ...
children = [<matplotlib.patches.Rectangle object at 0x0000024...
clip_box = None
clip_on = True
clip_path = None
constrained_layout = False
constrained_layout_pads = (0.04167, 0.04167, 0.02, 0.02)
contains = None
default_bbox_extra_artists = [<matplotlib.axes._subplots.AxesSubplot object at ...
dpi = 72.0
edgecolor = (1.0, 1.0, 1.0, 0.0)
facecolor = (1.0, 1.0, 1.0, 0.0)
figheight = 3.0
figure = None
figwidth = 4.0
frameon = True
gid = None
in_layout = True
label =
path_effects = []
picker = None
rasterized = None
size_inches = [4. 3.]
sketch_params = None
snap = None
tight_layout = False
transform = IdentityTransform()
transformed_clip_path_and_affine = (None, None)
url = None
visible = True
window_extent = TransformedBbox( Bbox(x0=0.0, y0=0.0, x1=4.0, ...
zorder = 0
print( plt.getp(f, "axes"), plt.getp(f, "axes")[0] is plt.gca())
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000024C0FFD9588>] True
alllines = plt.getp(plt.gca(), "lines")
print( alllines, alllines[0] is line) # 其中的第一條曲線就是最開始繪製的那條曲線
<a list of 3 Line2D objects> True
print( f.axes, len(f.axes[0].lines))
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000024C0FFD9588>] 3
繪製多子圖
可以使用subplot()快速繪製包含多個子圖的圖表,調用形式爲:subplot(numRows, numcols,plotNum).如果,numRows,numcols和plotNum三個參數都是小於10的,則可以把他們縮寫爲一個整數,例如:subplot(322)和subplot(3, 2, 3)的含義相同。
#%fig[1x2]=在Figure對象中創建多個子圖
for idx, color in enumerate("rgbyck"): # 三行兩列共六個子圖,並通過axisbg參數給每個子圖設置不同的背景顏色。
plt.subplot(321+idx, axisbg=color)
# 如果希望某個子圖佔據整行或者整列,可以如下調用subplot()
plt.subplot(221) # 第一行的左圖
plt.subplot(222) # 第一行的右圖
plt.subplot(212) # 第二整行;
plt.show()
#%hide
plt.close("all")
#%fig[1x2]=同時在多幅圖表、多個子圖中進行繪圖
plt.figure(1) # 創建圖表1
plt.figure(2) # 創建圖表2
ax1 = plt.subplot(121) # 在圖表2中創建子圖1
ax2 = plt.subplot(122) # 在圖表2中創建子圖2
x = np.linspace(0, 3, 100)
for i in range(5):
plt.figure(1) #❶ 選擇圖表1
plt.plot(x, np.exp(i*x/3))
plt.sca(ax1) #❷ 選擇圖表2的子圖1
plt.plot(x, np.sin(i*x))
plt.sca(ax2) # 選擇圖表2的子圖2
plt.plot(x, np.cos(i*x))
plt.show()
TIP
也可以不調用
sca()
指定當前子圖,而直接調用ax1
和ax2
的plot()
方法繪圖。
"""
這裏的axes是一個形狀爲:(2,3)的數組,每個元素都是一個子圖對象,可以利用Python的賦值語句功能將這個數組中的每個元素用一個變量來表示.
"""
#%nofig
fig, axes = plt.subplots(2, 3)
[a, b, c], [d, e, f] = axes
print( axes.shape)
print(b)
AxesSubplot(0.125,0.536818;0.227941x0.343182)
"""還可使用subplot2grid()進行更加複雜的表格佈局。表格佈局和Excel或者word中繪製表格十分類似"""
'還可使用subplot2grid()進行更加複雜的表格佈局。表格佈局和Excel或者word中繪製表格十分類似'
調用形式:subplot2grid(shape, loc, rowspan=1, colspan=1, **kwargs) 。其中,shape爲表示表格形狀的元組(行數,列數)。loc爲子圖左上角所在的座標:(行,列)。rowspan和colspan分別爲子圖所佔據的行數和列數。下面是在3X3的網格上創建5個子圖。在每個子圖中,顯示該子圖對應的變量名。
#%fig=使用subplot2grid()創建表格佈局
fig = plt.figure(figsize=(6, 6))
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
ax2 = plt.subplot2grid((3, 3), (0, 2), rowspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 0), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 1), colspan=2)
ax5 = plt.subplot2grid((3, 3), (1, 1));
#%hide
for idx, ax in enumerate(fig.axes, 1):
ax.text(0.5, 0.5, "ax{}".format(idx), ha="center", va="center", fontsize=16)
配置文件
前面的繪圖過程中,沒有逐一對圖表的屬性進行配置,而是直接採用matplotlib的默認配置。matplotlib將這些默認配置保存在一個名字爲matplotlibrc的配置文件中,通過修改配置文件,可以修改圖表的默認樣式。
from os import path
path.abspath(matplotlib.get_configdir())
u'C:\\Users\\RY\\Dropbox\\scipybook2\\settings\\.matplotlib'
path.abspath(matplotlib.matplotlib_fname())
u'C:\\Users\\RY\\Dropbox\\scipybook2\\settings\\.matplotlib\\matplotlibrc'
print(matplotlib.rc_params())
agg.path.chunksize: 0
animation.avconv_args: []
animation.avconv_path: avconv
animation.bitrate: -1
...
print(matplotlib.rcParams)
agg.path.chunksize: 0
animation.avconv_args: []
animation.avconv_path: avconv
animation.bitrate: -1
...
#%hide
plt.close("all")
%%disabled
matplotlib.rcParams["lines.marker"] = "o"
plt.plot([1,2,3,2])
%%disabled
matplotlib.rc("lines", marker="x", linewidth=2, color="red")
%%disabled
matplotlib.rcdefaults()
%%disabled
matplotlib.rcParams.update( matplotlib.rc_params() )
TIP
通過
pyplot
模塊也可以使用rcParams
、rc
和rcdefaults
。
matplotlib.style模塊提供繪圖樣式切換功能,所有可選樣式可以通過available獲得。
from matplotlib import style
print( style.available)
['bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark-palette', 'seaborn-dark', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'seaborn', 'Solarize_Light2', 'tableau-colorblind10', '_classic_test']
# 調用use()函數可以切換樣式,下面使用ggplot樣式繪圖。
style.use("ggplot")
#%figonly=使用ggplot樣式繪圖
import numpy as np
import matplotlib.pyplot as plt
style.use("ggplot")
plt.close("all")
x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2)
plt.figure(figsize=(8,4))
plt.plot(x,y,label="$sin(x)$",linewidth=2)
plt.plot(x,z,"--",label="$cos(x^2)$")
plt.xlabel("Time(s)")
plt.ylabel("Volt")
plt.title("ggplot style")
plt.ylim(-1.2,1.2)
plt.legend() # 顯示圖示,在圖中表示每條曲線的標籤(label)和樣式的矩形區域。
<matplotlib.legend.Legend at 0x24c11950a08>
在圖表中顯示中文
from matplotlib.font_manager import fontManager
fontManager.ttflist[:6]
[<Font 'cmsy10' (cmsy10.ttf) normal normal 400 normal>,
<Font 'cmss10' (cmss10.ttf) normal normal 400 normal>,
<Font 'cmb10' (cmb10.ttf) normal normal 400 normal>,
<Font 'DejaVu Serif' (DejaVuSerif-BoldItalic.ttf) italic normal bold normal>,
<Font 'cmtt10' (cmtt10.ttf) normal normal 400 normal>,
<Font 'DejaVu Serif' (DejaVuSerif-Italic.ttf) italic normal 400 normal>]
ttflist是matplotlib的系統字體列表。其中每個元素是表示字體的Font對象,如下:顯示第一個字體的全路徑和字體名。
print (fontManager.ttflist[0].name)
print (fontManager.ttflist[0].fname)
cmsy10
D:\installation\anaconda3\lib\site-packages\matplotlib\mpl-data\fonts\ttf\cmsy10.ttf
#%hide
plt.close("all")
scpy2/matplotlib/chinese_fonts.py
SOURCE
scpy2/matplotlib/chinese_fonts.py
:顯示系統中所有文件大於1M的TTF字體,請讀者使用該程序查詢計算機中可使用的中文字體名。
#%fig=顯示系統中所有的中文字體名
import os
from os import path
fig = plt.figure(figsize=(8, 7))
ax = fig.add_subplot(111)
plt.subplots_adjust(0, 0, 1, 1, 0, 0)
plt.xticks([])
plt.yticks([])
x, y = 0.05, 0.05
fonts = [font.name for font in fontManager.ttflist if
path.exists(font.fname) and os.stat(font.fname).st_size>1e6] #❶
font = set(fonts)
dy = (1.0 - y) / (len(fonts) // 4 + (len(fonts)%4 != 0))
for font in fonts:
t = ax.text(x, y + dy / 2, u"中文字體",
{'fontname':font, 'fontsize':14}, transform=ax.transAxes) #❷
ax.text(x, y, font, {'fontsize':12}, transform=ax.transAxes)
x += 0.25
if x >= 1.0:
y += dy
x = 0.05
plt.show()
#%nofig
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14) #❶
t = np.linspace(0, 10, 1000)
y = np.sin(t)
plt.close("all")
plt.plot(t, y)
plt.xlabel(u"時間", fontproperties=font) #❷
plt.ylabel(u"振幅", fontproperties=font)
plt.title(u"正弦波", fontproperties=font)
plt.show()
爲了縮短啓動時間,matplotlib不會在每次啓動時都重新掃描所有的字體文件並創建字體列表,因此在複製完字體文件之後,需要運行下面的語句重新創建字體列表。
from matplotlib.font_manager import _rebuild
_rebuild()
也可以直接修改配置字典,設置默認的字體。這樣就不需要在每次繪製文字時設置字體
%%disabled
plt.rcParams["font.family"] = "SimHei"
plt.plot([1,2,3])
plt.xlabel(0.5 ,0.5, u"中文字體")
#%hide
%exec_python -m scpy2.matplotlib.chinese_fonts