matplotlib詳細教學

来源:https://www.cnblogs.com/FavoriteStar/archive/2022/11/26/16928478.html
-Advertisement-
Play Games

Matplotlib初相識 認識matplotlib Matplotlib是一個Python 2D繪圖庫,能夠以多種硬拷貝格式和跨平臺的互動式環境生成出版物質量的圖形,用來繪製各種靜態,動態,互動式的圖表 一個最簡單的繪圖例子 matplotlib的圖像都是畫在對應的figure上,可以認為是一個繪 ...


Matplotlib初相識

認識matplotlib

Matplotlib是一個Python 2D繪圖庫,能夠以多種硬拷貝格式和跨平臺的互動式環境生成出版物質量的圖形,用來繪製各種靜態,動態,互動式的圖表

一個最簡單的繪圖例子

matplotlib的圖像都是畫在對應的figure上,可以認為是一個繪圖區域。而一個figure又可以包含一個或者多個axes,可以認為是子區域,這個子區域可以指定屬於自己的坐標系。下麵通過簡單的實例進行展示:

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
fig, ax = plt.subplots()  # 該函數創建一個包含1個axes的figure,並將兩者進行返回
ax.plot([1,2,3,4],[1,4,2,3])

第一圖

那麼也可以用更為簡單的方式來進行創建:

line = plt.plot([1,2,3,4],[1,4,2,3])

這是因為如果未指定axes,那麼會自動創建一個,因此可以簡化。

figure的組成

通常,一個完成的matplotlib圖像會包括四個層級(容器):

  • Figure:頂級層,用來容納所有繪圖元素
  • Axes:matplotlib宇宙的核心,容納了大量元素用來構造一幅幅的子圖,一個figure可以由1個或者多個子圖構成
  • Axis:axes的下層,用來處理所有與坐標軸、網格相關的元素
  • Tick:axis的下層,用來處理所有和刻度相關的元素

圖2

兩種繪圖介面

matplotlib提供了兩種最常用的繪圖介面:

  • 創建figure和axes,然後在此之上調用繪圖方法
  • 依賴pyplot自動創建figure和axes來繪圖

就像是上小節所展示的那樣兩種創建圖的方法。

通用繪圖模板

Datawhale提供了一個通常的繪圖模板,可以根據實際需要對該模板進行修改了補充:

# 先準備好數據
x = np.linspace(0, 2, 100)
y = x**2
# 設置繪圖樣式(非必須)
mpl.rc('lines', linewidth=4, linestyle='-.')
# 定義佈局
fig, ax = plt.subplots()  
# 繪製圖像
ax.plot(x, y, label='linear')  
# 添加標簽,文字和圖例
ax.set_xlabel('x label') 
ax.set_ylabel('y label') 
ax.set_title("Simple Plot")  
ax.legend() ;

圖3


思考題

  • 請思考兩種繪圖模式的優缺點和各自適合的使用場景

    • 我覺得先創建figure和axes再進行繪圖的方式更適用於你對圖的規劃比較清晰,或者你想要畫多個子圖,這樣在同一個figure上作畫會簡潔方便;而pyplot模型更實用於你當前只需要畫一個圖,那麼把所有元素都加到當前這個圖上就可以了
  • 在第五節繪圖模板中我們是以OO模式作為例子展示的,請思考並寫一個pyplot繪圖模式的簡單模板

    • plt.plot(x,y,label='linear')
      plt.xlabel("x label")
      plt.ylabel("y label")
      plt.title("simple plot")
      plt.legend()
      

藝術畫筆見乾坤

先準備待會兒要用到的庫

import numpy as np
import pandas as pd
import re
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D   
from matplotlib.patches import Circle, Wedge
from matplotlib.collections import PatchCollection

概述

matplotlib的三層api

matplotlib的原理或者說基礎邏輯是,用Artist對象在畫布(canvas)上繪製(Render)圖形。因此跟人作畫類似,需要三個步驟:

  • 準備一個畫圖
  • 準備畫筆、顏料
  • 作畫

因此可以認為matplotlib有三層的API:

  • matplotlib.backend_bases.FigureCanvas 代表了繪圖區,所有的圖像都是在繪圖區完成的
  • matplotlib.backend_bases.Renderer 代表了渲染器,可以近似理解為畫筆,控制如何在 FigureCanvas 上畫圖。
  • matplotlib.artist.Artist 代表了具體的圖表組件,即調用了Renderer的介面在Canvas上作圖。

因此我們大部分是利用Artist類來進行繪圖。

Artist的分類

Artist有兩種類型:primitivescontainers

  • primitive是基本要素,包含一些我們要在繪圖區作圖用到的標準圖形對象,例如曲線、文字、矩形等等。
  • container是容器,可以認為是用來放置基本要素的地方,包括圖形figure,坐標系axes和坐標系axis

基本元素primitives

primitives主要有以下幾種類型,我們按照順序介紹。

2DLines

其中常見的參數主要有:

  • xdata:橫坐標的取值,預設就是range(1,len(data)+1)
  • ydata:縱坐標取值
  • linewidth:線條的寬度
  • linestyle:線型
  • color:線條的顏色
  • marker:點的標註樣式
  • markersize:標註的大小
如何設置參數屬性

對於上面提到的各個參數有三種修改方法:

  • 在plot函數裡面進行設置

    x = range(0,5)
    y = [2,5,7,9,11]
    plt.plot(x,y,linewidth = 10)  
    
  • 獲取線對象,對線對象進行設置

    x = range(0,5)
    y = [2,5,7,8,10]
    line, = plt.plot(x, y, '-') # 這裡等號坐標的line,是一個列表解包的操作,目的是獲取plt.plot返回列表中的Line2D對象,返回是一個列表類型
    line.set_antialiased(False); # 關閉抗鋸齒功能,調用線對象的函數
    
  • 獲取線屬性,使用setp函數設置

    x = range(0,5)
    y = [2,5,7,8,10]
    lines = plt.plot(x, y)
    plt.setp(lines, color='r', linewidth=10);
    
如何繪製lines

那我們常見的功能是繪製直線line,以及繪製errorbar誤差折線圖,下麵對這兩種分別進行介紹。


繪製line

可以採用兩種方法來繪製直線:

1、plot方法

x = range(0,5)
y1 = [2,5,7,8,10]
y2= [3,6,8,9,11]
fig,ax= plt.subplots()
ax.plot(x,y1)
ax.plot(x,y2)
print(ax.lines); 

圖4

列印為:

<Axes.ArtistList of 2 lines>

可以看到創建了2個lines對象。

2、Line2D對象繪製

x = range(0,5)
y1 = [2,5,7,8,10]
y2= [3,6,8,9,11]
fig,ax= plt.subplots()
lines = [Line2D(x, y1), Line2D(x, y2,color='orange')]  # 顯式創建Line2D對象,但是現在還沒有在哪裡展示
for line in lines:
    ax.add_line(line) # 使用add_line方法將創建的Line2D添加到子圖中,才會展示
ax.set_xlim(0,4)
ax.set_ylim(2, 11);

圖5


繪製errorbar誤差折線圖

是利用pyplot中的errorbar類來實現,其參數為:

  • x:橫坐標
  • y:縱坐標
  • yerr:指定在y軸水平的誤差
  • xerr:指定在x軸水平的誤差
  • fmt:指定折線圖中某個點的顏色、形狀、線條風格等
  • ecolor:指定errorbar的顏色
  • elinewidth:指定errorbar的線條寬度

那麼具體的繪製方法就是將plot更改為errorbar即可:

fig = plt.figure()
x = np.arange(10)
y = 2.5 * np.sin(x / 20 * np.pi)
yerr = np.linspace(0.05, 0.2, 10)
plt.errorbar(x,y+3,yerr=yerr,fmt='o-',ecolor='r',elinewidth=2);

圖6


patches

這個類是二維圖形類,它最常見的可以用來繪製矩形、多邊形、楔形。

矩形

Rectangle矩形類比較簡單,主要是通過xy來控制錨點,然後控制矩形的高寬即可。

最常見的矩形圖是hist直方圖和bar條形圖

hist-直方圖

其函數為plt.hist(),那麼參數為:

  • x:數據集,直方圖將會對這個數據集進行統計
  • bins:統計的區間分佈,我們可以指定區間進行統計,例如按照([0,10],[11,20])區間進行統計
  • range:tuplt,顯示的區間
  • density:是否顯示頻數統計結果
  • histtype:可選{'bar', 'barstacked', 'step', 'stepfilled'}之一,預設為bar,step使用的是梯狀,stepfilled則會對梯狀內部進行填充,效果與bar類似
  • align:可選{'left', 'mid', 'right'}之一,預設為'mid',控制柱狀圖的水平分佈,left或者right,會有部分空白區域,推薦使用預設
  • log:y軸是否採用指數刻度
  • stacked:是否為堆積狀圖
x=np.random.randint(0,100,100) #生成[0-100)之間的100個數據,即 數據集 
bins=np.arange(0,101,10) #設置連續的邊界值,即直方圖的分佈區間[0,10),[10,20)... 
fig = plt.figure(figsize = (6,12))
plt.subplot(311)
plt.hist(x,bins,color='fuchsia',alpha=0.5, density = True, histtype="step", 
        align = "left")#alpha設置透明度,0為完全透明 
plt.xlabel('scores') 
plt.ylabel('count') 
plt.xlim(0,100); #設置x軸分佈範圍 plt.show()
plt.subplot(312)
plt.hist(x,bins,color='fuchsia',alpha=0.5, density = True, histtype="step", 
        align = "mid")
plt.subplot(313)
plt.hist(x,bins,color='fuchsia',alpha=0.5, density = True, histtype="step", 
        align = "right")

這裡對比了一下參數align的區別:

圖7

bar-柱狀圖

同樣,也是採用plt.bar()函數,其參數為:

  • left:x軸的位置序列,一般採用range函數產生一個序列,但是有時候可以是字元串
  • height:y軸的數值序列,也就是柱形圖的高度,一般就是我們需要展示的數據
  • alpha:透明度,值越小越透明
  • width:柱形的寬度
  • color或者facecolor:柱形填充的顏色
  • edgecolor:柱形邊緣顏色
  • label:標簽
y = range(1,17)
plt.bar(np.arange(16), y, alpha=0.5, width=0.5, color='yellow', edgecolor='red', label='The First Bar', lw=2);
# lw是柱形描邊的線寬度

圖8

多邊形

Polygon類是多邊形類,其參數主要是繪製的多邊形的頂點坐標。

那麼這個類中最常用的是fill類,它是基於頂點坐標繪製一個填充的多邊形,例如:

x = np.linspace(0, 5 * np.pi, 1000) 
y1 = np.sin(x)
y2 = np.sin(2 * x) 
plt.fill(x, y1, color = "g", alpha = 0.3);

圖8

楔型(餅狀圖)

一個楔型是以坐標xy為中心,半徑r,從角度1掃到角度2。最常用是繪製餅狀圖plt.pie()

其參數為:

  • x:楔型的形狀,一維數組,可以看成是掃過角度的大小
  • explode:如果不是None,那麼就是一個len(x)的數組,用來指定每塊的偏移
  • labels:指定每個塊的標簽,列表或者none
  • colors:指定每個塊的顏色,列表或者none
  • startangle:餅狀圖開始繪製的角度
labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
sizes = [15, 30, 45, 10] 
explode = (0, 0.1, 0, 0) 
fig1, ax1 = plt.subplots() 
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90) 
ax1.axis('equal');  # 設置axes為等高寬比,這樣才能夠確保畫出來為圓形

餅狀圖

collections

這個類是用來繪製一組對象的集合,那麼最常見的是用來繪製散點圖,即scatter方法,根據xy繪製不同大小或者顏色標記的散點圖。

其主要的參數如下:

  • x和y
  • s:散點的尺寸大小
  • c:顏色
  • marker:標記類型
x = [0,2,4,6,8,10] 
y = [10]*len(x) 
s = [20*2**n for n in range(len(x))] 
plt.scatter(x,y,s=s) ;

散點圖

image

這是繪製圖像的類,最常用的imshow可以根據數組繪製成圖像(數值是各個像素值)。

使用imshow畫圖時首先需要傳入一個數組,數組對應的是空間內的像素位置和像素點的值,interpolation參數可以設置不同的差值方法,可以理解為不同像素之間的處理手段:

methods = [None, 'none', 'nearest', 'bilinear', 'bicubic', 'spline16',
           'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric',
           'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos']


grid = np.random.rand(4, 4)

fig, axs = plt.subplots(nrows=3, ncols=6, figsize=(9, 6),
                        subplot_kw={'xticks': [], 'yticks': []})

for ax, interp_method in zip(axs.flat, methods):
    ax.imshow(grid, interpolation=interp_method, cmap='viridis')
    ax.set_title(str(interp_method))

plt.tight_layout()  # 自動調整子圖使其填充整個圖像

imshow函數

對象容器-Object container

前面我們介紹的primitives基礎元素,是包含在容器裡面的,當然容器還會包含它自身的屬性。

Figure容器

figure是最頂層的一個容器,它包含了圖中的所有元素,而一個圖表的背景可以認為就是在figure中添加的一個矩形。

當我們向圖表中添加add_subplot或者add_axes時,這些元素會被添加到figure.axes列表中:

fig = plt.figure()
ax1 = fig.add_subplot(211) # 作一幅2*1的圖,選擇第1個子圖
ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3]) # 再添加一個子圖位置參數,四個數分別代表了(left,bottom,width,height)
ax3 = fig.add_axes([0.2,0.1,0.3,0.4])  # 添加第三個子圖
print(ax1) 
print(fig.axes) # fig.axes 中包含了subplot和axes兩個實例, 剛剛添加的

子圖

可以看到如果添加的子圖位置重疊的可能存在的情況。而輸出結果為:

AxesSubplot(0.125,0.53;0.775x0.35)
[<AxesSubplot:>, <Axes:>, <Axes:>]

figure.axes的列表中當前有三個元素,代表三個子圖。

而我們可以通過figure.delaxes()來刪除其中的圖表,或者可以通過迭代訪問列表中的元素獲取子圖表,再在其上做修改:

fig = plt.figure()
ax1 = fig.add_subplot(211) # 作一幅2*1的圖,選擇第1個子圖
ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3]) # 再添加一個子圖位置參數,四個數分別代表了(left,bottom,width,height)
ax3 = fig.add_axes([0.2,0.1,0.3,0.4])
print(ax1) 
print(fig.axes) # fig.axes 中包含了subplot和axes兩個實例, 剛剛添加的
for ax in fig.axes:
    ax.grid(True)

子圖加上網格

Axes容器

Axes是matplotlib的核心。大量的用於繪圖的Artist存放在它內部,並且它有許多輔助方法來創建和添加Artist給它自己,而且它也有許多賦值方法來訪問和修改這些Artist

和figure類似,axes包含一個patch屬性,這個可以認為就是它的繪圖區域:

fig = plt.figure()
ax = fig.add_subplot(111)
rect = ax.patch  # 獲取實例
rect.set_facecolor("blue")

axespatch

Axes有許多方法用於繪圖,如.plot()、.text()、.hist()、.imshow()等方法用於創建大多數常見的primitive(如Line2D,Rectangle,Text,Image等等)。

可以在任意區域創建Axes,通過Figure.add_axes([left,bottom,width,height])來創建一個任意區域的Axes,其中left,bottom,width,height都是[0—1]之間的浮點數,他們代表了相對於Figure的坐標。

而我們往axes裡面添加圖表是通過add_line和add_patch來進行添加。

另外Axes還包含兩個最重要的Artist container:

  • ax.xaxis:XAxis對象的實例,用於處理x軸tick以及label的繪製
  • ax.yaxis:YAxis對象的實例,用於處理y軸tick以及label的繪製

Axis容器

該容器用來處理跟坐標軸相關的屬性,它包括坐標軸上的刻度線、刻度label、坐標網格、坐標軸標題等,而且可以獨立對上下左右四個坐標軸進行處理。

可以通過下麵的方法獲取坐標軸的各個屬性實例:

fig, ax = plt.subplots()
x = range(0,5)
y = [2,5,7,8,10]
plt.plot(x, y, '-')

axis = ax.xaxis # axis為X軸對象
axis.get_ticklocs()     # 獲取刻度線位置
axis.get_ticklabels()   # 獲取刻度label列表(一個Text實例的列表) 
axis.get_ticklines()    # 獲取刻度線列表(一個Line2D實例的列表)
axis.get_data_interval()# 獲取軸刻度間隔
axis.get_view_interval()# 獲取軸視角(位置)的間隔

也可以對獲取的屬性進行修改,例如:

fig = plt.figure() # 創建一個新圖表
rect = fig.patch   # 矩形實例並將其設為黃色
rect.set_facecolor('lightgoldenrodyellow')

ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4]) # 創一個axes對象,從(0.1,0.3)的位置開始,寬和高都為0.4,
rect = ax1.patch   # ax1的矩形設為灰色
rect.set_facecolor('lightslategray')


for label in ax1.xaxis.get_ticklabels(): 
    # 調用x軸刻度標簽實例,是一個text實例
    label.set_color('blue') # 顏色
    label.set_rotation(45) # 旋轉角度
    label.set_fontsize(14) # 字體大小

for line in ax1.yaxis.get_ticklines():
    # 調用y軸刻度線條實例, 是一個Line2D實例
    line.set_markeredgecolor('green')    # 顏色
    line.set_markersize(25)    # marker大小
    line.set_markeredgewidth(2)# marker粗細

修改axis

Tick容器

它是axis下方的一個容器對象,包含了tick、grid、line實例以及對應的label。我們可以訪問它的屬性來獲取這些實例:

  • Tick.tick1line:Line2D實例
  • Tick.tick2line:Line2D實例
  • Tick.gridline:Line2D實例
  • Tick.label1:Text實例
  • Tick.label2:Text實例

y軸分為左右兩個,因此tick1對應左側的軸;tick2對應右側的軸。

x軸分為上下兩個,因此tick1對應下側的軸;tick2對應上側的軸。

例如我們做如下修改:

fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))
ax.yaxis.set_tick_params(which='major', labelcolor='blue',
                         labelleft=False, labelright=True);

設置右軸

將主軸設在右邊且修改其顏色。


思考題

  • primitives 和 container的區別和聯繫是什麼,分別用於控制可視化圖表中的哪些要
    • 【答】:我認為container是一個容器,而primitives 是基本元素,可以理解為container是包容primitives的,例如figure,axes,axis等作為一個容器,它們可以包含很多primitives 的基礎元素在其上面進行展示
  • 使用提供的drug數據集,對第一列yyyy和第二列state分組求和,畫出下麵折線圖。PA加粗標黃,其他為灰色。
import pandas as pd
df = pd.read_csv("Drugs.csv")
df.head(5)
new_df = df.groupby(["YYYY","State"]).sum()
new_df

1

data = new_df.reset_index().pivot(index='YYYY', columns='State', values='DrugReports')
data

2

data = data.reset_index()
data

3

因此就可以開始繪圖了:

fig,ax = plt.subplots(figsize = (12,12))

ax.grid(True, color='white')
rect = ax.patch
rect.set_facecolor('#efefef')

ax.plot(data["YYYY"], data["KY"],color='#afafaf')
ax.plot(data["YYYY"], data["OH"],color='#afafaf')
ax.plot(data["YYYY"], data["PA"],color='yellow',linewidth='8')
ax.plot(data["YYYY"], data["VA"],color='#afafaf')
ax.plot(data["YYYY"], data["WV"],color='#afafaf')

ax.set_title('Evolution of PA vs other states', color='yellow', loc='left')
ax.set_xlabel('Year')
ax.set_ylabel('DrugReports')

作業圖1

  • 分別用一組長方形柱和填充面積的方式模仿畫出下圖,函數 y = -1 * (x - 2) * (x - 8) +10 在區間[2,9]的積分面積
import numpy as np
x = np.linspace(0,10)
y = -1 * (x - 2) * (x - 8) + 10
fig,ax = plt.subplots(2,1,figsize = (8,12))
x_bar = np.linspace(2,9)
y_bar = -1 * (x_bar - 2) * (x_bar - 8) + 10
y_bar_button = y_bar * 0
ax[0].plot(x,y,color="red")
ax[1].plot(x,y,color="red")
ax[0].bar(x_bar, y_bar,width=0.1, color='lightgray')
ax[1].bar(x_bar, y_bar, width = 0.1, color='lightgray')
ax[0].set_ylim((0,20))
ax[1].set_ylim((0,20))
ax[1].fill_between(x_bar, y_bar, y_bar_button, color="lightgray")

作業圖2

佈局格式定方圓

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']   #用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False   #用來正常顯示負號

子圖

使用plt.subplots()繪製均勻狀態下的子圖

該函數的返回分別是畫布和子圖構成的列表,傳入的參數為行、列、第幾個子圖,figsize用來指定畫布的大小,sharex和sharey用來表示是否共用橫軸和縱軸刻度,tight_layout用來調整子圖的相對大小使字元不重疊:

fig, axs = plt.subplots(2,5, figsize = (10,4), sharex = True, sharey = True)
fig.suptitle("樣例1",size = 20)
for i in range(2):
    for j in range(5):
        axs[i][j].scatter(np.random.randn(10), np.random.randn(10))
        axs[i][j].set_title('第%d行,第%d列'%(i+1,j+1))
        axs[i][j].set_xlim(-5,5)
        axs[i][j].set_ylim(-5,5)
        if i==1: axs[i][j].set_xlabel('橫坐標')
        if j==0: axs[i][j].set_ylabel('縱坐標')
fig.tight_layout()

子圖樣例1

前面是利用subplots(註意加了s)顯式的創建多個對象,然後一一進行畫圖;我們還可以通過plt和subplot(註意沒加s),每次在指定位置創建子圖,創建後當前的繪製都會指向該子圖:

plt.figure()
# 子圖1
plt.subplot(2,2,1) 
plt.plot([1,2], 'r')
# 子圖2
plt.subplot(2,2,2)
plt.plot([1,2], 'b')
#子圖3
plt.subplot(224)  # 當三位數都小於10時,可以省略中間的逗號,這行命令等價於plt.subplot(2,2,4) 
plt.plot([1,2], 'g');

子圖樣例2

除了常規的直角坐標系,還可以用projection方法創建極坐標系下的圖表:

N = 300
r = 2 * np.random.rand(N)
theta = 2 * np.pi * np.random.rand(N)
area = 50 * r**2
colors = theta


plt.subplot(projection='polar')
plt.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75);

極坐標圖


練一練

請思考如何用極坐標系畫出類似的玫瑰圖

fig = plt.figure(figsize = (8,12))
ax = plt.subplot(projection = "polar")
x = np.arange(100,1000, 20)  # 間隔為20
y = np.linspace(0,np.pi*2, len(x))
ax.set_theta_direction(-1)  # 設置極坐標的方向為順時針,1為逆時針
ax.set_theta_zero_location('N')  # 設置開始畫的方位,有8個方位
ax.bar(y, x, width = 0.15,color=np.random.random((len(r), 3)))
plt.tight_layout()  

主要就是set_theta_direction和set_theta_zero_location兩個函數調整圖像。

極坐標2

使用GridSpec繪製非均勻子圖

所謂非均勻包含兩層含義,第一是指圖的比例大小不同但沒有跨行或跨列,第二是指圖為跨列或跨行狀態

利用 add_gridspec 可以指定相對寬度比例 width_ratios 和相對高度比例參數 height_ratios

fig = plt.figure(figsize=(10, 4))
spec = fig.add_gridspec(nrows=2, ncols=5, width_ratios=[1,2,3,4,5], height_ratios=[1,3])
fig.suptitle('樣例2', size=20)
for i in range(2):
    for j in range(5):
        ax = fig.add_subplot(spec[i, j])  # 註意此處的調用方式
        ax.scatter(np.random.randn(10), np.random.randn(10))
        ax.set_title('第%d行,第%d列'%(i+1,j+1))
        if i==1: ax.set_xlabel('橫坐標')
        if j==0: ax.set_ylabel('縱坐標')
fig.tight_layout()

子圖樣例3

上述創建子圖時用到了spec[i,j]的方法,說明它是一個可索引的列表,那麼同樣也可以對其採用切片:

fig = plt.figure(figsize=(10, 4))
spec = fig.add_gridspec(nrows=2, ncols=6, width_ratios=[2,2.5,3,1,1.5,2], height_ratios=[1,2])
fig.suptitle('樣例3', size=20)
# sub1
ax = fig.add_subplot(spec[0, :3])  # 高度取第一個,寬度前三個都要了,就是1,7.5
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub2
ax = fig.add_subplot(spec[0, 3:5]) # 1,1+1.5
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub3
ax = fig.add_subplot(spec[:, 5])
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub4
ax = fig.add_subplot(spec[1, 0])
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub5
ax = fig.add_subplot(spec[1, 1:5])
ax.scatter(np.random.randn(10), np.random.randn(10))
fig.tight_layout()

子圖樣例4

子圖上的方法

補充一些子圖上的常用方法。


常用來畫直線的方法為axhline, axvline, axline (水平、垂直、任意方向)

fig, ax = plt.subplots(figsize=(4,3))
ax.axhline(0.5,0.1,0.8, color = 'red')  
# 第一個參數為水平y等於多少,第二個為xmin,第三個為xmax,都是浮點數代表坐標軸占百分比
ax.axvline(0.5,0.2,0.8, color = "blue")
ax.axline([0.3,0.3],[0.7,0.7], color = "green");

子圖畫直線


利用grid可以添加灰色網格:

fig, ax = plt.subplots(figsize=(4,3))
ax.grid(True)

子圖網格


使用set_xscale或者set_yscale可以設置坐標軸的刻度:

fig, axs = plt.subplots(1, 2, figsize=(10, 4))
for j in range(2):
    axs[j].plot(list('abcd'), [10**i for i in range(4)])
    if j==0:
        axs[j].set_yscale('log')
    else:
        pass
fig.tight_layout()

對數刻度


思考題

  • 墨爾本1981年至1990年的每月溫度情況
data = pd.read_csv("layout_ex1.csv")
data["Time"] = pd.to_datetime(data["Time"])
data["year_num"] = data["Time"].apply(lambda x: x.year)
fig, ax = plt.subplots(2, 5, figsize = (20,4))
fig.suptitle('墨爾本1981年至1990年月溫度曲線',size=20,y=1.1)
for i in range(2):
    for j in range(5):
        tem = data[data["year_num"] == j+1981+i*5]["Temperature"]
        x = np.arange(0,12)
        ax[i][j].plot(x,tem,marker = "o",color='b')
        ax[i][j].set_title(str(j+1981 + i*5 ) + "年")
        if( j == 0):
            ax[i][j].set_ylabel("氣溫")
plt.tight_layout()

墨爾本溫度

  • np.random.randn(2, 150) 生成一組二維數據,使用兩種非均勻子圖的分割方法,做出該數據對應的散點圖和邊際分佈圖
data = np.random.randn(2,150)
fig = plt.figure(figsize = (12,12))
spec = fig.add_gridspec(nrows = 2, ncols = 2,width_ratios = [3,1],height_ratios=[1,3])
ax = fig.add_subplot(spec[0,0])
ax.hist(data[0,:],color = "blue",width = 0.4)
ax.axis("off")
ax2 = fig.add_subplot(spec[1,1])
ax2.hist(data[1,:], orientation='horizontal',color = "blue",rwidth = 0.8)
# 第二個參數設置為在y上面
ax2.axis("off")
ax3 = fig.add_subplot(spec[1,0])
ax3.scatter(data[0,:],data[1,:],color = "blue")
ax3.grid(True)
ax3.set_ylabel("my_data_y")
ax3.set_xlabel("my_data_x")
plt.tight_layout()

作業題2

文字圖例盡眉目

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
import datetime

Figure和Axes上的文本

文本API示例

下麵這些命令是通過pyplot API和ooAPI分別創建文本的方式:

5


fig = plt.figure()
ax = fig.add_subplot()
# 設置x和y軸標簽
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# 設置x和y軸顯示範圍均為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})
# 在畫布上添加文本,一般在子圖上添加文本是更常見的操作,這種方法很少用
fig.text(0.4,0.8,'This is text for figure')
ax.plot([2], [1], 'o')
# 添加註解
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
            arrowprops=dict(facecolor='black', shrink=0.05));

文本樣例1

text-子圖上的文本

其調用方法為axes.text()。那麼其參數為:

  • x,y:文本出現的位置
  • s:文本的內容
  • fontdict:可選參數,用來調整文本的屬性

重點解釋下fontdict和**kwargs參數,這兩種方式都可以用於調整呈現的文本樣式,最終效果是一樣的,不僅text方法,其他文本方法如set_xlabel,set_title等同樣適用這兩種方式修改樣式。通過一個例子演示這兩種方法是如何使用的。

fig = plt.figure(figsize = (10,3))
axes = fig.subplots(1,2)
axes[0].text(0.3,0.8, "modift by **kwargs", style="italic",
            bbox = {"facecolor":"red", "alpha":0.5, "pad": 10})
font = {"bbox": {"facecolor":"red", "alpha":0.5, "pad": 10},
       "style":"italic"}
axes[1].text(0.3,0.8, "modify by fontdict", fontdict = font)

文本樣例2

那麼這些樣式常用的參數如下:

111

222

xlabel和ylabel

其調用方法為axes.set_xlabel和axes.set_ylabel

其參數為:

  • xlabel:標簽內容
  • fontdict和之前一樣
  • **kwargs也和之前一樣
  • labelpad:標簽和坐標軸之間的距離
  • loc:標簽位置,可選為"left","center","right"

在**kwargs中有另外的參數可以調整標簽的位置等信息,下麵來觀察他們的區別:

fig = plt.figure(figsize=(10,3))
axes = fig.subplots(1,2)
axes[0].set_xlabel('xlabel',labelpad=20,loc='left')


# loc參數僅能提供粗略的位置調整,如果想要更精確的設置標簽的位置,可以使用position參數+horizontalalignment參數來定位
# position由一個元組過程,第一個元素0.2表示x軸標簽在x軸的位置,第二個元素對於xlabel其實是無意義的,隨便填一個數都可以
# horizontalalignment='left'表示左對齊,這樣設置後x軸標簽就能精確定位在x=0.2的位置處
axes[1].set_xlabel('xlabel', position=(0.2, _), horizontalalignment='left');

標簽樣例

title和suptitle-子圖和畫布的標題

title調用方法為axes.set_title(),其參數為:

  • label:標簽內容
  • fontdict,loc,**kwargs和之前一樣
  • pad:標題偏離圖表頂部的位置
  • y:title所在子圖垂向的位置,預設在子圖的頂部

suptitle的調用為figure.suptitle()。

下麵查看pad和y的影響:

fig = plt.figure(figsize=(10,3))
fig.suptitle('This is figure title',y=1.2) # 通過參數y設置高度
axes = fig.subplots(1,2)
axes[0].set_title('This is title,pad = 15',pad=15)
axes[1].set_title('This is title,pad = 6',pad=6);
fig = plt.figure(figsize=(10,3))
fig.suptitle('This is figure title2',y=1) 
axes = fig.subplots(1,2)
axes[0].set_title('This is title,y = 1',y = 1)
axes[1].set_title('This is title,y = 1.2',y = 1.2);

pad樣例

y樣例

可以看到兩者其實就是控制標題與圖的距離而已。

annotate-子圖的註解

調用方式為axes.annotate(),其參數為:

  • text:註解的內容
  • xy:註解箭頭指向的位置
  • xytext:註解文字的坐標
  • xycoords:用來定義xy參數的坐標系
  • textcoords:用來定義xytext參數的坐標系
  • arrowprops:用來定義指向箭頭的樣式

其參數特別多樣化,這裡只是舉個例子:

fig = plt.figure()
ax = fig.add_subplot()
ax.annotate("annotate1",
            xy=(0.2, 0.2), xycoords='data',
            xytext=(0.8, 0.8), textcoords='data',
            arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.2")
            );

箭頭實例

字體的屬性設置

字體設置一般有全局字體設置和自定義局部字體設置兩種方法。

為了方便在圖中加入合適的字體,可以嘗試瞭解中文字體的英文名稱,此鏈接中就有常用的中文字體的英文名

#該block講述如何在matplotlib裡面,修改字體預設屬性,完成全局字體的更改。
plt.rcParams['font.sans-serif'] = ['SimSun']    # 指定預設字體為新宋體。
plt.rcParams['axes.unicode_minus'] = False      # 解決保存圖像時 負號'-' 顯示為方塊和報錯的問題。
#局部字體的修改方法1
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) ;   # 小示例圖的字體設置

字體1

tick上的文本

設置tick(刻度)和ticklabel(刻度標簽)也是可視化中經常需要操作的步驟,matplotlib既提供了自動生成刻度和刻度標簽的模式(預設狀態),同時也提供了許多靈活設置的方式。

簡單模式

直接使用axis.set_ticks設置標簽位置,使用axis.set_ticklabels設置標簽格式:

x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
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.));

tick1

可以自動設置相對來說會好一點(上圖)

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

tick2

我們通常設置tick都是要與數值的範圍匹配, 然後再設置ticklabel為我們想要的類型,如下:


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('top')
#set_ticks_position()方法是用來設置刻度所在的位置,常用的參數有bottom、top、both、none
print(axs[1].xaxis.get_ticklines());

tick4

上方的例子就是位置在bottom,下方就是在top,both就是上下都有,none就是都沒有。

Tick Lacators and Formatters

除了上述的簡單模式以外,還可以通過Axis.set_major_locatorAxis.set_minor_locator方法用來設置標簽的位置,Axis.set_major_formatterAxis.set_minor_formatter方法用來設置標簽的格式。這種方式的好處是不用顯式地列舉出刻度值列表。

set_major_formatter和set_minor_formatter這兩個formatter格式命令可以接收字元串格式(matplotlib.ticker.StrMethodFormatter)或函數參數(matplotlib.ticker.FuncFormatter)來設置刻度值的格式 。

這部分的內容比較推薦用到的時候再去查。

Tick Formatters

接受字元串:

fig, axs = plt.subplots(2, 2, figsize=(12, 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);

tick3

接受函數:

def formatoddticks(x, pos):
    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);

tick5

Tick Locators

這個實現更複雜的操作:

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=3)
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);

tick6

# 特殊的日期型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);

tick7

legend圖例

在學習legend之前需要先學習幾個術語:

  • legend entry(圖例條目):每個圖例都有一個或者多個條目組成,一個條目包含一個key和對應的label,例如圖中三條曲線需要標註,那麼就是3個條目
  • legend key(圖例鍵):每個legend label左邊的標記,指明是哪條曲線
  • legend label(圖例標簽):描述文本
  • legend handle(圖例句柄):用於在圖例中生成適當圖例條目的原始對象

以下圖為例,右側的方框中的共有兩個legend entry;兩個legend key,分別是一個藍色和一個黃色的legend key;兩個legend label,一個名為‘Line up’和一個名為‘Line Down’的legend label

示例圖

圖例的繪製同樣有OO模式和pyplot模式兩種方式,寫法都是一樣的,使用legend()即可調用。

fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend(handles = [line_up, line_down], labels = ['Line Up', 'Line Down']);

legend1

fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend()

legend2

而設置圖例的位置,可以通過設置loc參數的值來設置,其有10個位置可以選擇,每個都有字元串的形式和對應的數字形式:

Location String Location Code
best 0
upper right 1
upper left 2
lower left 3
lower right 4
right 5
center left 6
center right 7
lower center 8
upper center 9
center 10
fig,axes = plt.subplots(2,5,figsize=(15,5))
for i in range(2):
    for j in range(5):
        axes[i][j].plot([0.5],[0.5])
        axes[i][j].legend(labels='a',loc=i*5+j)  # 觀察loc參數傳入不同值時圖例的位置
fig.tight_layout()

legend3

還可以設置圖例的邊框和背景:

fig = plt.figure(figsize=(10,3))
axes = fig.subplots(1,3)
for i, ax in enumerate(axes):
    ax.plot([1,2,3],label=f'ax {i}')
axes[0].legend(frameon=False) #去掉圖例邊框
axes[1].legend(edgecolor='blue') #設置圖例邊框顏色
axes[2].legend(facecolor='gray'); #設置圖例背景顏色,若無邊框,參數無效

legend4

也可以為圖例加上標題:

fig,ax =plt.subplots()
ax.plot([1,2,3],label='label')
ax.legend(title='legend title');

legend5


思考題

嘗試使用兩種方式模仿畫出下麵的圖表(重點是柱狀圖上的標簽),本文學習的text方法和matplotlib自帶的柱狀圖標簽方法bar_label

第一種

label = ["Jim","Slim","Harry","Dick","Tom"]
y = [4,7,6,8,10]
error = np.random.rand(len(y)).round(2) #誤差
fig,ax = plt.subplots()
ax.set_title("How fast do you want to go today?")
ax.set_xlim(0,15)
for i in range(0, len(y)):
    ax.text(y[i] + error[i]+1, label[i], '±' + str(error[i]), fontsize=10,horizontalalignment='center',color='blue')
ax.set_xlabel('performance')
ax.barh(label, y, color = 'blue',xerr = error)
# barh有一個參數為xerr就是來畫誤差線的
label = ["Jim","Slim","Harry","Dick","Tom"]
y = [4,7,6,8,10]
error = np.random.rand(len(y)).round(2) #誤差
fig,ax = plt.subplots()
ax.set_title("How fast do you want to go today?")
ax.set_xlim(0,15)
ax.set_xlabel('performance')
b = ax.barh(label, y, color = 'blue',xerr = error)
plt.bar_label(b, ["±"+str(i) for i in error])

思考題

樣式色彩秀芳華

第五回詳細介紹matplotlib中樣式和顏色的使用

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

matplotlib的繪圖樣式(style)

設置樣式最簡單就是在繪製每一個元素時在參數中設定對應的樣式,不過也可以用方法來批量修改全局的樣式。

matplotlib預先定義樣式

只需要在python腳步最開始時輸入想使用的style的名稱就可以調用,那麼我們可以查看有哪些方式方便使用:

print(plt.style.available)
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']

那麼使用方法例如:

plt.style.use('ggplot')
plt.plot([1,2,3,4],[2,3,4,5]);

樣式例子1

用戶自定義stylesheet

在任意路徑下創建一個尾碼名為mplstyle的樣式清單,編輯文件添加以下樣式內容:

axes.titlesize : 24
axes.labelsize : 20
lines.linewidth : 3
lines.markersize : 10
xtick.labelsize : 16
ytick.labelsize : 16

引用自定義stylesheet後觀察圖表變化:

plt.style.use('style1.mplstyle')
plt.plot([1,2,3,4],[2,3,4,5]);

樣式例子2

值得特別註意的是,matplotlib支持混合樣式的引用,只需在引用時輸入一個樣式列表,若是幾個樣式中涉及到同一個參數,右邊的樣式表會覆蓋左邊的值:

plt.style.use(['dark_background', 'style1.mplstyle'])
plt.plot([1,2,3,4],[2,3,4,5]);

樣式例子3

設置rcparams

還可以通過修改預設rc設置的方式改變樣式,所有rc設置都保存在一個叫做 matplotlib.rcParams的變數中。修改過後再繪圖,可以看到繪圖樣式發生了變化。

plt.style.use('default') # 恢復到預設樣式
mpl.rcParams['lines.linewidth'] = 2
mpl.rcParams['lines.linestyle'] = '--'
plt.plot([1,2,3,4],[2,3,4,5]);

樣式例子4

另外matplotlib也還提供了一種更便捷的修改樣式方式,可以一次性修改多個樣式。

mpl.rc('lines', linewidth=4, linestyle='-.')

matplotlib的色彩設置color

在matplotlib中,設置顏色有以下幾種方式

RGB或者RGBA

plt.plot([1,2,3],[4,5,6],color=(0.1, 0.2, 0.5))
plt.plot([4,5,6],[1,2,3],color=(0.1, 0.2, 0.5, 0.5));

顏色用[0,1]之間的浮點數表示,四個分量按順序分別為(red, green, blue, alpha),其中alpha透明度可省略。

顏色樣例1

HEX RGB或者RGBA

# 用十六進位顏色碼表示,同樣最後兩位表示透明度,可省略
plt.plot([1,2,3],[4,5,6],color='#0f0f0f')
plt.plot([4,5,6],[1,2,3],color='#0f0f0f80');

顏色樣例2

灰度色階

# 當只有一個位於[0,1]的值時,表示灰度色階
plt.plot([1,2,3],[4,5,6],color='0.5');

顏色楊麗3

單字元基本顏色

八個基本顏色可以用單個字元來表示,分別是'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w',對應的是blue, green, red, cyan, magenta, yellow, black, and white的英文縮寫,設置color='m'即可。

顏色名稱

matplotlib提供了顏色對照表,可供查詢顏色對應的名稱

素材對照

用colormap設置一組顏色

具體可以閱讀這篇文章

x = np.random.randn(50)
y = np.random.randn(50)
plt.scatter(x,y,c=x,cmap='RdYlBu');

顏色4


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 摘要:近日,經過全球知名獨立認證機構SGS Brightsight實驗室的安全評估,華為雲GaussDB企業級分散式資料庫內核獲得全球權威信息技術安全性評估標準CC EAL4+級別認證 本文分享自華為雲社區《國內唯一!GaussDB拿下的安全認證CC EAL4+究竟有多難?》,作者:GaussDB ...
  • # HTTPS server server { listen 443; server_name ************.com; ssl on; ssl_certificate cert/************.com.pem; ssl_certificate_key cert/******** ...
  • 一、數據類型存儲 在JavaScript中存在兩大數據類型:基本類型、引用類型。 基本數據類型存放在棧中,是一段簡單的數據段,數據大小確定,記憶體空間大小可以分配,是直接按值存放的,可以按值訪問。 引用數據類型存放在堆中,變數在棧中保存的是指向堆記憶體的地址值,這個地址值指向對應的對象類型,訪問堆記憶體中 ...
  • 摘要:在競爭如此激烈的當下,作為一名IT新人,怎麼才能讓HR眼前一亮,從萬千簡歷中脫穎而出成為最亮的那個崽呢? 本文分享自華為雲社區《【一行代碼秒上雲】連夜自建網站背刺我的求職對手們 !》,作者:AppCloud小助手。 前言 在競爭如此激烈的當下,作為一名IT新人,怎麼才能讓HR眼前一亮,從萬千簡 ...
  • Apache-Commons-* 字元串 判斷字元串是否為空白字元串 以前判斷字元串是否為空: if ((name == null) || (name.isEmpty())){} 使用 apache-common-lang3 的 StringUtils: void testIsBlank() { / ...
  • 伺服器端渲染技術02 11.EL表達式 11.1EL表達式介紹 EL表達式全稱:Expression Language,是表達式語言 EL表達式主要是代替jsp頁面的表達式腳本 EL表達式輸出數據時,比jsp的表達式腳本簡潔 EL表達式基本語法:${key} 底層其實走的還是jsp表達式腳本,可以理 ...
  • Lambda 表達式(Lambda Expression),相信大家對 Lambda 肯定是很熟悉的,畢竟我們數學上經常用到它,即 λ 。不過,感覺數學中的 Lambda 和編程語言中的 Lambda 表達式沒啥關係,要說有關係就是都有 Lambda 這個詞,噢!當然還有一個關係就是 Lambda ... ...
  • 1.匿名函數 # 1.匿名函數lambda # 簡化代碼 減少占用的記憶體 print('1.匿名函數lambda') def func(): print(10) func() func = lambda: print(10) # 出現警告的原因是: # 因為你把lambda表達式賦給了另一個變數。 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...