matplotlib:python數據處理三劍客之一


1.基本使用

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# 生成一系列x
x = np.linspace(-1, 1, 50)
# 生成對應的y
y1 = 2 * x +1
y2 = x ** 2
# 傳入對應的x和y,調用plot方法,繪制圖像
# plot會將所有的點連起來
plt.plot(x, y1)
plt.plot(x, y2)
plt.show()

2.調整圖像大小

x = np.linspace(-1, 1, 50)
y1 = 2 * x +1
y2 = x ** 2
# 圖像是畫在畫布上面的
plt.figure(figsize=(8, 5))
plt.plot(x, y1)
plt.plot(x, y2)
plt.show()

3.繪制基本圖形(折線圖)

3.1 基本繪制

x = np.linspace(-1, 1, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))
# 其實之前介紹過了,就是使用plot方法即可
plt.plot(x, y1)
plt.plot(x, y2)
plt.show()

3.2 設置樣式

x = np.linspace(-1, 1, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))

# linestyle:表示線段的樣式
# color:表示顏色
# marker:表示點的樣式
plt.plot(x, y1, linestyle="-", color="cyan", marker="o")
plt.plot(x, y2, linestyle="--", color="red", marker="<")
plt.show()

關於樣式:

  • linestyle

    '-' solid line style
    '--' dashed line style
    '-.' dash-dot line style
    ':' dotted line style
    
  • marker

    '.'       point marker
    ','       pixel marker
    'o'       circle marker
    'v'       triangle_down marker
    '^'       triangle_up marker
    '<'       triangle_left marker
    '>'       triangle_right marker
    '1'       tri_down marker
    '2'       tri_up marker
    '3'       tri_left marker
    '4'       tri_right marker
    's'       square marker
    'p'       pentagon marker
    '*'       star marker
    'h'       hexagon1 marker
    'H'       hexagon2 marker
    '+'       plus marker
    'x'       x marker
    'D'       diamond marker
    'd'       thin_diamond marker
    '|'       vline marker
    '_'       hline marker
    

4.設置坐標軸

4.1 設置坐標軸范圍和描述

# 將x修改一下, 改成-10到10
x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))

plt.plot(x, y1, linestyle="-", color="cyan", marker="o")
plt.plot(x, y2, linestyle="--", color="red", marker="<")

plt.xlim([-5, 5])  # 設置x坐標軸的范圍是-5到5
plt.ylim([-10, 20])  # 設置y坐標軸的范圍是-10到20
# 調整坐標軸范圍還可以使用plt.axis([-5, 5, -10, 20])這種形式
plt.xlabel("i am x axis")  # 設置x軸描述
plt.ylabel("i am y axis")  # 設置y軸描述
plt.show()

4.2 設置坐標軸刻度

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))

plt.plot(x, y1, linestyle="-", color="cyan", marker="o")
plt.plot(x, y2, linestyle="--", color="red", marker="<")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  

# 坐標軸屬性可以通過gca = plt.gca()獲取
# 然后通過gca.屬性去調節
# 但是對於坐標軸刻度的話,和坐標軸范圍一樣,是可以直接通過plt來調節的
plt.locator_params(nbins=20)  # 表示將軸分成20份
# 如果只想對某一個軸,比如x軸去調節的話,可以通過plt.locator_params("x", nbins=20)

plt.show()
# 怎么樣,是不是變密了呢?

4.3 設置坐標軸傾斜角度以及曲線標記

我們注意到x軸的刻度雖然多了,但是快連在一起,我們可不可以讓其歪一些呢?這樣就不會連接一起了,而且圖上面有兩個曲線,我們可不可以給每個曲線做個標記呢?

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))

# 做標記的話,只需要加上一個label參數即可
plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  
plt.locator_params(nbins=20)  

# 通過plt.xticks調整x軸刻度,同理y軸的話就是yticks
plt.xticks(rotation=60)  # 傾斜60度

# 這一步是為了讓plot中設置的label顯示出來,沒有這一句是不會顯示的
# 而且會自動幫我們找到一個合適的位置
plt.legend() # 還可以加上一個loc='best',會尋找最好的位置,這里沒有加,位置也是不錯的
plt.show()

4.4 設置網格

背景光禿禿的,不是很好看,我們也可以設置一些網格

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))
plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  
plt.locator_params(nbins=20)  
plt.xticks(rotation=60) 
plt.legend() 

# 設置網格
plt.grid(color="pink")  # 此外plt.title("title")還可以設置標題
plt.show()

可以看到,需要什么樣式,直接設置即可,會疊加在一起。我們這里的plot是折線圖,而這些樣式、屬性啊在其他大部分圖形上都是通用的

4.5 自定義坐標軸

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))
plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  
plt.locator_params(nbins=20)  
plt.xticks(rotation=60) 
# 將2 4 6 8換成對應的英文
plt.yticks([2, 4, 6, 8], ["two", "four", "six", "eight"])
plt.legend() 

plt.grid(color="green")
plt.show()

但是這樣其他的刻度就沒了,因此我們只能手動調整。

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))
plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  
plt.locator_params(nbins=20)  
plt.xticks(rotation=60) 

# 將坐標軸替換
y_axis = list(range(-10, 20, 2))
new_y_axis = list(map(lambda x: "two" if x == 2 else "four" if x == 4 else "six" if x == 6 else "eight" if x == 8 else x, y_axis))
plt.yticks(y_axis, new_y_axis)
plt.legend() 

plt.grid(color="green")
plt.show()

4.6 設置邊框屬性

我們發現目前的圖形是一個矩形,也就是有四條線,如果我們想只有左邊和下邊的線呢?

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))
plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  
plt.locator_params(nbins=20)  
plt.xticks(rotation=60) 
plt.legend() 

# 獲取坐標軸
gca = plt.gca()  # get current axis
# gca.spines拿到四個坐標軸,left、right、top、bottom,將上邊和右邊的坐標軸的顏色設置為none,隱藏起來即可
gca.spines["right"].set_color("none")  
gca.spines["top"].set_color("none")  
# 將左邊和下邊的顏色設置成粉色和綠色,顯眼一點
gca.spines["left"].set_color("pink")
gca.spines["bottom"].set_color("green")
plt.show()

4.7 調整移動坐標軸

目前坐標軸不是我們上學學的那種二維直角坐標系,怎么變成那種坐標系呢?

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))
plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  
plt.locator_params(nbins=20)  
plt.xticks(rotation=60) 
plt.legend() 

gca = plt.gca()  # get current axis
gca.spines["right"].set_color("none")  
gca.spines["top"].set_color("none")  
gca.spines["left"].set_color("pink")
gca.spines["bottom"].set_color("green")

# 寫法比較固定,將下邊的左邊的軸的位置設置為('data', 0)
gca.spines['bottom'].set_position(('data', 0))
gca.spines['left'].set_position(('data',0))

plt.show()

可以看到,坐標軸移動了。但是這樣有一個缺陷,那就是坐標軸的描述還處在原來的位置,和坐標軸以及刻度重疊了

x = np.linspace(-10, 10, 50)
y1 = 2 * x +1
y2 = x ** 2
plt.figure(figsize=(8, 5))
plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")

plt.xlim([-5, 5])  
plt.ylim([-10, 20])  
plt.xlabel("i am x axis")  
plt.ylabel("i am y axis")  
plt.locator_params(nbins=20)  
plt.xticks(rotation=60) 
plt.legend() 

gca = plt.gca()  # get current axis
gca.spines["right"].set_color("none")  
gca.spines["top"].set_color("none")  
gca.spines["left"].set_color("pink")
gca.spines["bottom"].set_color("green")

gca.spines['bottom'].set_position(('data', 0))
gca.spines['left'].set_position(('data',0))

# 將x軸刻度設置為上方
# y軸刻度設置為右方
gca.xaxis.set_ticks_position("top")
gca.yaxis.set_ticks_position("right")

plt.show()

感覺這樣好白痴啊,不過無所謂,知道有這么個語法就可以了,也不常用

4.8 添加注釋

x = np.arange(-10, 11)
y = x ** 2
plt.plot(x, y)
plt.annotate("my name is satori",
            xy=(0, 5),  # 箭頭坐標
            xytext=(0, 20),  # 文本坐標
            arrowprops={
                "facecolor": "red",  # 顏色
                "headlength": 10,  # 箭頭長度
                "headwidth": 30,  # 箭頭的頭的寬度,
                "width": 20  # 箭頭的身體的寬度
            })
plt.show()

5.繪制基本圖形(散點圖)

x = np.random.normal(0, 1, 1024)
y = np.random.normal(0, 1, 1024)
# 散點圖使用scatter函數,半藏的散
plt.scatter(x, y)
plt.show()

當然散點圖也可以指定樣式

plt.figure(figsize=(10, 8))
x = np.random.normal(0, 1, 100)
y = np.random.normal(0, 1, 100)

# s:點的大小
# color:顏色,不指定默認為藍色
# marker:形狀,不指定默認為點。marker和plot里面的marker是一樣的
# alpha:透明度,不指定默認為1
plt.scatter(x, y, s=75, color="green", marker="<", alpha=0.2)
plt.show()

關於顏色的問題,其實還有一個參數c,這個c是一個數組。舉個例子吧,plt.scatter([1, 2, 3, 4], [2, 4, 6, 8], c=[0, 1, 1, 0]),首先x和y組合會形成四個點,坐標分別是(1, 2), (2, 4), (3, 6), (4, 8),而c是與之等長的數組,c是[0, 1, 1, 0],那么按照索引對應,如果對應c中是0的都是一個顏色,對應到1的都是一個顏色。我們在機器學習,對樣本進行聚類的時候,就可以將樣本標簽(label)做為c,這樣的話,不同的樣本特征就會對應不同的顏色,這樣通過顏色我們可以看出聚類的效果好不好。

plt.figure(figsize=(10, 8))
# x和y都是-10到10
x = np.random.randint(-10, 10, 100)
y = np.random.randint(-10, 10, 100)
c = []
for v in zip(x, y):
    # 如果x+y<0,我們分類為0
    # 如果0<=x+y<10,我們分類為1
    # 如果10<=x+y<20,我們分類為2
    if sum(v) < 0:
        c.append(0)
    elif sum(v) < 10:
        c.append(1)
    else:
        c.append(2)
        
plt.scatter(x, y, c=c)
plt.show()

可以看出紫色的點是兩個坐標之和小於0的,綠色的則是坐標之和位於0到10的,黃色的是坐標之和位於10到20的。

plt.figure(figsize=(10, 8))
# x和y都是-10到10
x = np.random.normal(-1, 1, 1000)
y = np.random.normal(-1, 1, 1000)
c = np.arctan2(y, x)

plt.axis([-1.5, 1.5, -1.5, 1.5])
gca = plt.gca()
gca.spines["left"].set_color("none")
gca.spines["right"].set_color("none")
gca.spines["top"].set_color("none")
gca.spines["bottom"].set_color("none")
# 如果xticks或者yticks里面傳入一個空元祖或者空列表的話表示隱藏掉坐標軸
plt.xticks(())
plt.yticks([])

plt.scatter(x, y, s=100, c=c, alpha=0.5)
plt.show()

6.繪制基本圖形(條形圖)

plt.figure(figsize=(10, 8))
# 還記得每一個圖對應的每一個函數嗎?
# 散點圖:scatter
# 折線圖:plot
# 條形圖:bar

# 這個函數可以只接收兩個參數,分別是條形圖中每一條的索引和高度
plt.bar(x=[0, 1, 2, 3, 4, 5], height=[11, 22, 33, 44, 55, 66])
plt.show()

當然也可以指定樣式

plt.figure(figsize=(10, 8))

# facecolor:條形圖內部填充色
# edgecolor:條形圖邊框顏色
# width:寬度
plt.bar(x=[0, 1, 2, 3, 4, 5], height=[11, 22, 33, 44, 55, 66],
        edgecolor="blue",
        color="green",
        width=0.2)
plt.show()

繪制多個條形圖

plt.figure(figsize=(10, 8))
X =[0, 1, 2, 3, 4, 5]
height1 = [11, 22, 33, 44, 55, 66]
height2 = [-11, -22, -33, -44, -55, -66]
plt.bar(X,height1,
        edgecolor="blue",
        color="green",
        width=0.2)

plt.bar(X, height2,
        edgecolor="pink",
        color="red",
        width=0.2)

# 但是這樣不夠用美觀,我們可以把軸隱藏掉
# 對應值標記在對應條形圖的上下方
for x, y in zip(X, height1):
    # x, y表示坐標,我們上移一點,那么x保持不變,y增大一點
    # 第三個y則表示的是對應值
    # ha表示橫向,v表示縱向,center是居中,bottom向下對其
    plt.text(x, y+0.1, y, ha="center", va="bottom")
    
for x, y in zip(X, height2):
    # 這里的y要減少一點,因為向下的條形圖部分
    plt.text(x, y-0.1, y, ha="center", va="top")
    
plt.show()

7.繪制基本圖形(等高線圖)

n=256
x=np.linspace(-3,3,n)
y=np.linspace(-3,3,n)
X,Y=np.meshgrid(x,y)

#f函數用來計算高度值 
def f(x,y):
    return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)

# 利用contour函數把顏色加進去 位置參數依次為X,Y,f(X,Y),8, 透明度為0.75,並將f(X,Y)的值對應到camp之中
plt.contourf(X,Y,f(X,Y),8,alpha=0.75,cmap=plt.cm.hot)# 8表示等高線分成多少份 alpha表示透明度 cmap表示color map
#使用plt.contour函數進行等高線繪制 參數依次為x,y,f(x,y),顏色選擇黑色,線條寬度為0.5
C=plt.contour(X,Y,f(X,Y),8,colors='black',linewidth=0.5)
#使用plt.clabel添加高度數值 inline控制是否將label畫在線里面,字體大小為10
plt.clabel(C,inline=True,fontsize=10)
plt.xticks(())#隱藏坐標軸
plt.yticks(())
plt.show()

8.繪制基本圖形(直方圖)

mu = 100
sigma = 20
x = mu + sigma * np.random.randn(2000)

# 設置直方圖
# bins:表示要分成多少個區間
# normed:表示是否進行標准化,標准化之后,阿么縱坐標不在是個數,而是頻率
plt.hist(x, bins=30, color="green", density=True)
plt.show()

9.繪制基本圖形(雙變量直方圖)

x = np.random.randn(1000)+2
y = np.random.randn(1000)+3
 
 
plt.hist2d(x, y, bins=40)
 
plt.show()

10.基本圖形繪制(餅圖)

labels = ["satori", "mashiro", "nagisa"]
fracs = [40, 30, 30]
 
# 最重要的兩個參數
# x:所占的份額
# labels:對應的標簽
plt.pie(x=fracs, labels=labels)
plt.show()

也可以指定樣式

labels = ["satori", "mashiro", "nagisa"]
fracs = [40, 30, 30]
 
# autopct:表示每一塊的比例
# explode:突出顯示,每個部分不會貼在一塊
# shadow:加上一層陰影,指定為True即可
plt.pie(x=fracs, labels=labels, autopct="%.0f%%", explode=[0.01, 0.2, 0.1], shadow=True)
plt.show()

11.基本圖形繪制(箱型圖)

np.random.seed(100)
data = np.random.normal(0, 1, size=1000)

# sym:形狀,表示異常值的形狀
# whis:表示虛線的長度,可以控制異常值顯示的多少,越大虛線越長
plt.boxplot(data, sym="<", whis=1.5)
plt.show()

12.3D圖形繪制(不常用)

from mpl_toolkits.mplot3d import Axes3D as A3
fig = plt.figure(figsize=(10, 8))
ax = A3(fig) 
x = np.arange(-4, 4, 0.2)
y = np.arange(-4, 4, 0.2)
x, y = np.meshgrid(x, y)
z = np.power(x, 2) + np.power(y, 2)
plt.title("satori")

# rstride,cstride表示行列每隔多少個點建一個面,cmap表示顏色
ax.plot_surface(x, y, z, rstride=1,
                cstride=1,
                cmap=plt.cm.CMRmap,
                alpha=0.4)
ax.set_xlabel('x_label', color='r')
ax.set_ylabel('y_label', color='g')
ax.set_zlabel('z_label', color='b')
 
plt.show()

13.多圖繪制

規則排列

方法一:

x = np.arange(1, 100, 5)
 
# 生成一個畫布
fig = plt.figure(figsize=(10, 8))
 
# 往畫布上添加對象
# 這里的221表示,將畫布分成2X2份,並處於第一個位置
# 222則是第二個位置,注意是先從左往右,再從上往下
s1 = fig.add_subplot(221)
s2 = fig.add_subplot(222)
s3 = fig.add_subplot(223)
s4 = fig.add_subplot(224)
y1 = np.log(x)
y2 = np.sin(x)
y3 = np.cos(x)
y4 = x ** 2

# 這里不再使用plt.plot,而是使用s
s1.plot(x, y1, color="green", marker="x", linestyle="--")
s2.plot(x, y2, color="blue", marker="o", linestyle="-.")
s3.plot(x, y3, color="cyan", marker="<", linestyle="--")
s4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
plt.show()

方法二:

import numpy as np
import matplotlib.pyplot as plt
 
x = np.arange(1, 100, 5)

plt.figure(figsize=(10, 8))
# 這里可以直接使用plt.subplot
plt.subplot(221)
plt.plot(x, np.log(x))
plt.subplot(222)
plt.plot(x, np.sin(x))
plt.subplot(223)
plt.plot(x, np.cos(x))
plt.subplot(224)
plt.plot(x, x**2)
 
plt.show()

這里沒有設置樣式,但是基本上是一樣的。

不規則排列

x = np.arange(1, 100, 5)
 
# 生成一個畫布
fig = plt.figure(figsize=(10, 8))


# 分成3行3列
"""
1 2 3
4 5 6
7 8 9
"""
s1 = fig.add_subplot(331)
s2 = fig.add_subplot(335)
s3 = fig.add_subplot(337)
s4 = fig.add_subplot(339)
y1 = np.log(x)
y2 = np.sin(x)
y3 = np.cos(x)
y4 = x ** 2

# 這里不再使用plt.plot,而是使用s
s1.plot(x, y1, color="green", marker="x", linestyle="--")
s2.plot(x, y2, color="blue", marker="o", linestyle="-.")
s3.plot(x, y3, color="cyan", marker="<", linestyle="--")
s4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
plt.show()

這樣盡管不規則,但是一張圖還是只占據一份的面積,比如第一張圖,如果我想讓其填滿其所在的一整行,該怎么辦呢?

x = np.arange(1, 100, 5)
 
# 生成一個畫布
fig = plt.figure(figsize=(10, 8))

# 先計算好,我要分為幾行顯示
# 比如第一張圖顯示第一行,填滿
# 第二張和第三張顯示在第二行
# 第四張顯示在第三行,填滿

# 先分成3行1列,選擇311,會把第一行占滿
s1 = fig.add_subplot(311)  
s2 = fig.add_subplot(323)  # 由於第一張圖把第一張占滿了,那么3X2的基礎上相當於1和2被占了,所以這里是323
s3 = fig.add_subplot(324)
s4 = fig.add_subplot(313)  # 這里是313,表示3X1,占滿第三行
y1 = np.log(x)
y2 = np.sin(x)
y3 = np.cos(x)
y4 = x ** 2

# 這里不再使用plt.plot,而是使用s
s1.plot(x, y1, color="green", marker="x", linestyle="--")
s2.plot(x, y2, color="blue", marker="o", linestyle="-.")
s3.plot(x, y3, color="cyan", marker="<", linestyle="--")
s4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
plt.show()

分格顯示

方法一:

fig = plt.figure(figsize=(10, 8))

# subplot2grid創建小圖
# (3, 3)表示將整個圖像分格為3行3列,(0, 0)表示從第1行和第1列開始
# colspan表示跨3列,還有一個rowspan,不指定默認為1
ax1 = plt.subplot2grid((3,3), (0, 0), colspan=3)
# 從第2行第1列開始,跨兩列
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
# 從第2行第3列開始,跨兩行
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
# 從第3行第1列開始,默認跨一行、一列
ax4 = plt.subplot2grid((3, 3), (2, 0))
# 從第3行第2列開始
ax5 = plt.subplot2grid((3, 3), (2, 1))
x = np.arange(1, 100, 5)
y1 = np.log(x)
y2 = np.sin(x)
y3 = np.cos(x)
y4 = x ** 2
y5 = (1 + np.exp(-x))

# 這里不再使用plt.plot,而是使用ax
ax1.plot(x, y1, color="green", marker="x", linestyle="--")
ax2.plot(x, y2, color="blue", marker="o", linestyle="-.")
ax3.plot(x, y3, color="cyan", marker="<", linestyle="--")
ax4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
ax5.plot(x, y5, color="yellow", marker=">", linestyle="-.")
plt.show()

當然也可以這么寫

fig = plt.figure(figsize=(10, 8))

x = np.arange(1, 100, 5)
y1 = np.log(x)
y2 = np.sin(x)
y3 = np.cos(x)
y4 = x ** 2
y5 = (1 + np.exp(-x))

plt.subplot2grid((3,3), (0, 0), colspan=3)
plt.plot(x, y1, color="green", marker="x", linestyle="--")

plt.subplot2grid((3, 3), (1, 0), colspan=2)
plt.plot(x, y2, color="blue", marker="o", linestyle="-.")

plt.subplot2grid((3, 3), (1, 2), rowspan=2)
plt.plot(x, y3, color="cyan", marker="<", linestyle="--")

plt.subplot2grid((3, 3), (2, 0))
plt.plot(x, y4, color="yellow", marker=">", linestyle="-.")

plt.subplot2grid((3, 3), (2, 1))
plt.plot(x, y5, color="yellow", marker=">", linestyle="-.")

plt.show()

方法二:

import matplotlib.gridspec as grid_spec  # 引入新的模塊
 
fig = plt.figure(figsize=(10, 8))

x = np.arange(1, 100, 5)
y1 = np.log(x)
y2 = np.sin(x)
y3 = np.cos(x)
y4 = x ** 2
y5 = (1 + np.exp(-x))

gs = grid_spec.GridSpec(3, 3)  # 還是將圖像分成3行3列

# plt.subplot2grid((3,3), (0, 0), colspan=3)
plt.subplot(gs[0, :])  # 占第一行和所有列
plt.plot(x, y1, color="green", marker="x", linestyle="--")

# plt.subplot2grid((3, 3), (1, 0), colspan=2)
plt.subplot(gs[1, : 2])
plt.plot(x, y2, color="blue", marker="o", linestyle="-.")

# plt.subplot2grid((3, 3), (1, 2), rowspan=2)
plt.subplot(gs[1: , 2])
plt.plot(x, y3, color="cyan", marker="<", linestyle="--")

# plt.subplot2grid((3, 3), (2, 0))
plt.subplot(gs[2, 0])
plt.plot(x, y4, color="yellow", marker=">", linestyle="-.")

# plt.subplot2grid((3, 3), (2, 1))
plt.subplot(gs[2, 1])
plt.plot(x, y5, color="yellow", marker=">", linestyle="-.")

plt.show()

14.添加坐標軸

plt.figure(figsize=(10, 8))

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# 調用subplot不加參數,得到相應坐標軸
ax1 = plt.subplot()
# 生成一個雙胞胎y軸
ax2 = ax1.twinx()

# 直接使用plt繪制即可,無需使用ax1和ax2,當然使用這兩個也能繪制。
plt.plot(x, y1, color="red", label="sin")
plt.plot(x, y2, color="green", label="cos")
plt.legend()
plt.show()

15.動畫

曲線的生成過程

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anime

%matplotlib notebook
fig = plt.figure(figsize=(10, 8))
plt.grid(color="pink", linestyle="--")

# 生成x,y數據
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

# plt.plot可以有返回值,這里必須是"ani,"  不是"ani" ,切記,否則動圖是不會生成的
# 這里的ani,拿到的是整個曲線
ani, = plt.plot(x, y)


# 構造函數,用來更新每一幀的x和y的值
# 參數i表示第i幀
def update_x_y(i):
    # 設置每一幀對應的曲線的坐標
    # 這里我們每次將x增大或者減小一點,這樣圖像才會移動
    # 至於增大或者減小的程度,由x決定
    # 讓圖像上的x的每個元素都隨着幀數的增加而增大,這樣就有了圖像向右邊走的效果
    ani.set_ydata(np.sin(x+i/100))
    return ani,   # 這里是要返回的,但是記住同樣是"ani," 不是"ani"


# 這里也要賦值,否則動圖不會顯示
# fig:繪圖對象
# func:更新動畫的函數
# frames:一共要多少幀,這里是一個數組,也可以直接傳入200
# interval:間隔
# blit:是否開啟渲染
f = anime.FuncAnimation(
    fig=fig,
    func=update_x_y,
    frames=np.arange(200),
    interval=20,
    blit=True
)

plt.show()

大概長這樣,聲明一下,我這圖像是在notebook里面生成的,但是我沒有ffmpeg,無法自動合並。因此只能以html形式保存,然后到本地變成了一大堆的png,然后手動使用imageio模塊,轉成了gif,因此曲線變化的速度可能不和notebook不一樣。

曲線不動,一個點在曲線上面走

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anime

%matplotlib notebook
fig = plt.figure(figsize=(10, 8))
plt.grid(color="pink", linestyle="--")

# 生成x,y數據
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

# 繪制整個圖像
plt.plot(x, y)
# 使用第一個點
ani, = plt.plot(x[0], y[0], color="green", marker="o")

# 構造函數,用來更新每一幀的x和y的值
# 參數i表示第i幀
def update_x_y(i):
    # set_ydata表示更新y的值,之前的ani,是用plt.plot(x, y)生成的,是一整條曲線
    # 這里的ani,是用plt.plot(x[0], y[0])生成的,是一個點
    # 而且這里是set_data,表示set_ydata,所以這里要傳入兩個參數,兩個參數組成一個點。
    # 隨着i的變化,這個點的坐標也在變化
    ani.set_data(x[i], y[i])
    return ani,   # 這里是要返回的,但是記住同樣是"ani," 不是"ani"


# 這里也要賦值,否則動圖不會顯示
# fig:繪圖對象
# func:更新動畫的函數
# frames:一共要多少幀,這里是一個數組,也可以直接傳入200
# interval:間隔
# blit:是否開啟渲染
f = anime.FuncAnimation(
    fig=fig,
    func=update_x_y,
    frames=np.arange(100),
    interval=100,
    blit=True
)

plt.show()

我們把點的坐標也加上去吧

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anime

%matplotlib notebook
fig = plt.figure(figsize=(10, 8))
plt.grid(color="pink", linestyle="--")

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

plt.plot(x, y)
ani, = plt.plot(x[0], y[0], color="green", marker="o")
text = plt.text(4, 0.5, "", fontsize=16)
# 構造函數,用來更新每一幀的x和y的值
# 參數i表示第i幀
def update_x_y(i):
    if i % 2 == 0:
        ani.set_marker("*")
        ani.set_markersize(20)
        ani.set_color("pink")
    else:
        ani.set_marker("o")
        ani.set_markersize(14)
        ani.set_color("blue")
    ani.set_data(x[i], y[i])
    text.set_position((x[i], y[i]))
    text.set_text(f"x={round(x[i], 3)} y={round(y[i], 3)}")
    return ani, text


f = anime.FuncAnimation(
    fig=fig,
    func=update_x_y,
    frames=np.arange(100),
    interval=100,
    blit=True
)
plt.show()

常見問題:

1.子圖重合的時候

加上plt.tight_layout()即可

2.當出現中文,顯示為亂碼的時候

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(5)
y = x + 3

plt.plot(x, y)
plt.xlabel("我是x軸")
plt.ylabel("我是y軸")
plt.show()

可以看到,label無法正常顯示

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(5)
y = x + 3

plt.rcParams['font.sans-serif'] = ['SimHei'] # 步驟一(替換sans-serif字體)
plt.rcParams['axes.unicode_minus'] = False   # 步驟二(解決坐標軸負數的負號顯示問題)

plt.plot(x, y)
plt.xlabel("我是x軸")
plt.ylabel("我是y軸")
plt.show()

正常顯示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM