Matplotlib繪圖及動畫總結


Matplotlib繪圖總結

繪圖原理

block模式(python默認)

  1. plt.polt()等繪圖函數不會直接在窗口中繪圖,只有調用plt.show()(默認block=True)或plt.pause()(窗口自動關閉)時才將內存中的圖繪制到窗口。

  2. 程序碰到第一個plt.show()時,繪圖后會暫停執行,直到手動關閉當前窗口才繼續執行后面的代碼,這就是“阻塞”的含義。

  3. plt.pause(time)函數也能實現窗口繪圖(不需要plt.show),但窗口只停留time時間便會自動關閉,然后再繼續執行后面代碼;plt.pause()會把它之前的所有繪圖都繪制在對應坐標系中,而不僅僅是在當前坐標系中繪圖;特別要注意的是,plt.pasue(0)將繪制之前的所有圖像,且圖像窗口不會自動關閉,但程序會停止在該語句所在位置,即使手動關閉窗口也不會繼續執行后面的代碼。

    # 測試程序
    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(0, 2 * np.pi, 0.1)
    y1 = np.sin(x)
    y2 = np.cos(x)
    
    plt.figure(1)
    plt.plot(x, y1)
    plt.pause(2)  #在figure(1)上繪制sin曲線,2s后自動關閉窗口
    
    plt.figure(1)
    plt.plot(x, y2)
    plt.pause(2)  #在figure(1)上繪制cos曲線,2s后自動關閉窗口
    

interactive模式(ipython模式默認)

  1. 開啟interactive模式,用plt.ion(),放在繪圖之前,關閉該模式用plt.ioff()

  2. 不用plt.show()plt.pause(),只要plt.plot()等語句就能在窗口中繪圖,但是,繪圖后窗口立馬自動關閉,你壓根都沒法看清楚;可以用plt.pause(time)進行延遲自動關閉時間,需要注意的是如果有多個plt.pause()穿插在不同繪圖函數下,那么前面的窗口不會先關閉,會等到最后一個plt.pause()結束后再一起關閉。該模式下要實現同時繪圖,且保持,可用plt.pause(0),但程序會結束在該位置,手動關閉窗口也不會繼續執行了,因此plt.pause(0)應放在程序最后。

  3. 該模式下,即使用了plt.show()也依然會自動關閉窗口,可在調用plt.show()之前調用plt.ioff()關閉交互模式,恢復到阻塞模式。

    import numpy as np
    import matplotlib.pyplot as plt
    
    plt.ion() #開啟interactive模式
    for i in range(100):
        y = np.random.random(size=10)
        #plt.cla() #清除當前圖像,若不清除則前面畫的圖保留
        plt.plot(y) #自動繪圖,但窗口會立即消失
        plt.pause(0.1) #用於保持窗口
    plt.ioff() #關閉interactive模式,否則后面的plt.show()也會一閃而過
    plt.show()
    

深入子圖

知道前面的原理可以滿足大多數的需要,但是如果如果想自定義每個圖的位置,大小,並從多個角度對數據進行比較、分析,則需要深入子圖。

子圖表示

四元列表:[x,y,width,height], 取值范圍都是[0, 1], 約定左下角為原點(0, 0), 右上角為(1, 1)。這些取值均為比例。

import numpy as np
import matplotlib.pyplot as plt

ax1 = plt.axes()
ax2 = plt.axes([0.5, 0.6, 0.2, 0.2])
plt.show(block=False)
plt.pause(10)

# 進階版
plt.figure(1)
ax1 = plt.axes()
plt.pause(2)
plt.figure(1)
ax2 = plt.axes([0.5, 0.6, 0.2, 0.2])
plt.show(block=False)
plt.pause(10)

子圖繪圖

每生成一個子圖坐標系,plt就表示當前的子圖,調用plt.plot()就是在當前的子圖上進行繪圖。

方法一:在一張圖上生成多種坐標系
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10) # 在[0, 10]之間均分50個點
plt.axes([0.1, 0.5, 0.8, 0.4], ylim=(-1.2, 1.2))  #
plt.grid(True)
plt.plot(np.sin(x))

plt.axes([0.1, 0.5, 0.8, 0.4], ylim=(-1.2, 1.2))
plt.grid(True)
plt.plot(np.cos(x))
plt.show()
方法二:調用plt.subplot()

無法繪制比例自定義的子圖

import numpy as np
import matplotlib.pyplot as plt

# 縱橫間隙
plt.subplots_adjust(hspace=0.3, wspace=0.3)
for i in range(1, 7):
    # 划分子圖,生成一張圖
    plt.subplot(2, 3, i)
    # 在當前子圖上書寫
    plt.text(0.5, 0.5, str((2, 3, i)), fontsize=18, ha='center')
plt.show()
方法三:子圖坐標軸共用

便於數據的比較、分析

import numpy as np
import matplotlib.pyplot as plt

# 返回子圖及其坐標軸
fig, ax = plt.subplots(2, 3, sharex='col', sharey='row')
for i in range(2):
    for j in range(3):
        ax[i, j].text(0.5, 0.5, str((i, j)), fontsize=18, ha='center')
plt.show()
方法四:子圖不規則

使用GridSpec方法

import numpy as np
import matplotlib.pyplot as plt

# 將一個區域划分為2行3列共6塊
grid = plt.GridSpec(2, 3, wspace=0.5, hspace=0.5)
plt.subplot(grid[0,0]) # 占第一行第一列一個塊
plt.subplot(grid[0,1:3]) # 占第一行第二、三列2個塊
plt.subplot(grid[1, 0:2]) # 同理
plt.subplot(grid[1,2]) # 同理

plt.show()

例子

import numpy as np
import matplotlib.pyplot as plt

mean = [0, 0]
cov = [[1, 1], [1, 4]]
x, y = np.random.multivariate_normal(mean, cov, 3000).T
plt.figure(figsize=(6, 6))
grid = plt.GridSpec(4, 4, wspace=0.5, hspace=0.5)

main_ax = plt.subplot(grid[0:3, 1:4])  # 0,1,2 rows, 1,2,3 col
plt.plot(x, y, 'ok', markersize=3, alpha=0.2)

y_hist = plt.subplot(grid[0:3, 0], xticklabels=[], sharey=main_ax)  # 和大子圖共y軸
plt.hist(y, 60, orientation='horizontal', color='gray')  # 圖形水平繪制
y_hist.invert_xaxis()  # x軸調換方向

x_hist = plt.subplot(grid[3, 1:4], yticklabels=[], sharex=main_ax)  # 和大子圖共x軸
plt.hist(x, 60, orientation='vertical', color='gray')
x_hist.invert_yaxis()  # y軸調換方向

plt.show()

繪制動畫

方法一:開啟交互模式

缺點無法保存

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
plt.ion()
ims = []
for i in range(1, 10):
    im = plt.plot(np.linspace(0, i, 10),
                  np.linspace(0, np.random.randint(i), 10))
    ims.append(im)
    plt.draw()
    plt.pause(0.8)
plt.ioff()

方法二:使用animation

可生成GIF文件,注意散點圖返回對象與其他不同,需調用findobj()返回Artis對象

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
if __name__ == "__main__":
    fig = plt.figure()
    ims = []
    for i in range(1, 10):
        im = plt.plot(np.linspace(0, i, 10),
                      np.linspace(0, np.random.randint(i), 10))
        ims.append(im)
    ani = animation.ArtistAnimation(fig, ims, interval=200, repeat_delay=1000)
    ani.save("test1.gif", writer='pillow')

import matplotlib.animation as animation
import matplotlib.pyplot as plt
ims = []
fig = plt.figure()
x = np.linspace(0, 10)  # 在[0, 10]之間均分50個點
plt.plot(x, np.sin(x), color='black')
for i in range(1, 10):
    im = plt.scatter(i, np.sin(i), color='r').findobj()
    ims.append(im)
ani = animation.ArtistAnimation(fig, ims, interval=200, repeat_delay=1000)
ani.save("test2.gif", writer='pillow')

參考鏈接

https://www.jianshu.com/p/276b7f3ecd4d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

https://blog.csdn.net/qq_28888837/article/details/85778395

[https://matplotlib.org/api/_as_gen/matplotlib.animation.ArtistAnimation.html?highlight=animation artistanimation](https://matplotlib.org/api/_as_gen/matplotlib.animation.ArtistAnimation.html?highlight=animation artistanimation)

https://juejin.im/post/5a7c4ab6f265da4e976e7feb


免責聲明!

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



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