天天看點

Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

前言

Matplotlib 可以将任何圖形渲染為各種常見的檔案格式,如 PNG、EPS、SVG 和 PDF。預設情況下,圖形顯示時帶有簡約的使用者界面,可以通過儲存按鈕将圖形儲存到檔案中。但是,如果需要生成大量的圖形,這種方法并不友善,是以我們需要使用函數自動化儲存生成的圖形檔案。在本文中,我們将探讨 Matplotlib 的檔案輸出功能。除了以程式設計方式生成檔案輸出外,我們還将學習如何控制輸出的分辨率和大小以及透明度等。

生成PNG圖檔檔案

實際使用場景下,我們可能希望擷取程式運作過程中資料的情況,同時并不想打斷程式的執行,而希望為每個運作步驟自動生成儲存一張圖檔。Matplotlib 可以靈活的将圖形直接儲存到圖檔檔案中。

首先,我們将學習如何将圖形輸出到 PNG 檔案。PNG 檔案是位圖輸出的理想選擇,它依賴于無損壓縮算法,并可以處理透明度。

import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(-6, 6, 1024)
y = np.sinc(x)
plt.plot(x, y)
plt.savefig('sinc.png', c = 'c')      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

Tips:要儲存圖檔,隻需使用 plt.savefig() 調用替換 plt.show() 調用,此時将不會彈出檢視圖形視窗。函數 plt.savefig() 的工作原理與 plt.show() 完全相同——解釋 plt 指令并生成圖形,差別在于處理結束時所做的操作。show() 函數将圖檔資料發送到使用者界面庫以進行展示,而 savefig() 函數将圖檔資料寫入檔案。

同時 savefig() 函數提供了多種可選參數,讓我們繼續前進,開始探索吧。

控制透明度

當圖形是網站或示範文稿的一部分時,圖形之間可能需要疊加顯示,透明度對于這樣的整合是很重要的,圖形必須以一種美學上令人愉悅和一緻的方式與背景融為一體。

為了示範透明性,将建立一個圖形并将其嵌入到網頁中,與網頁背景融為一體。

使用透明背景将圖形渲染為PNG檔案

為了将圖形渲染為透明背景的 PNG 檔案,需要使用 plt.savefig(),并将可選參數 transparent 設定為 True:

import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(-6, 6, 1024)
y = np.sinc(x)
plt.plot(x, y)
plt.savefig('sinc_1.png', c = 'c', transparent=True)      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

制作包含圖形的HTML頁面

在包含背景的網頁上使用上一步驟中儲存的 PNG 檔案(網頁背景圖檔 background.jpg 請替換為目錄中存在的檔案):

<html>
    <head>
        <style>
            body {
            background: white url(background.jpg);
            }
        </style>
    </head>
    <body>
        <img src='sinc_1.png' width='800 height='600'></img>
    </body>
</html>      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

預設情況下,plt.savefig() 不會在輸出中包含透明度資訊。例如,當我們輸出 PNG 圖檔時,PNG 檔案預設每像素 24bit,每個 8bit 的通道僅存儲像素的紅色、綠色和藍色分量。但是,當啟用透明輸出時,plt.savefig() 儲存的檔案每像素 32bit,附加的 alpha 通道存儲透明度資訊。

作為對比,如果我們使用不包含 alpha 通道的 sinc.png:

<html>
    <head>
        <style>
            body {
            background: white url(background.jpg);
            }
        </style>
    </head>
    <body>
        <img src='sinc.png' width='800 height='600'></img>
    </body>
</html>      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

通過系列文章的學習,我們知道可以通過在繪圖函數中(如 plt.plot、plt.scatter、pltpie 等)使用可選參數 alpha 控制 Matplotlib 生成的不同透明度級别的圖形。如果 alpha 等于 1,則圖形将完全不透明,這是預設設定;如果 alpha 等于 0,圖形将完全不可見。

import numpy as np
import matplotlib.pyplot as plt
name_list = ('Omar', 'Serguey', 'Max', 'Zhou', 'Abidin')
value_list = np.random.randint(99, size=len(name_list))
pos_list = np.arange(len(name_list))
plt.bar(pos_list, value_list, alpha = .75, color = 'c', align = 'center')
plt.xticks(pos_list, name_list)
plt.savefig('bar.png', transparent = True)      

在HTML頁面中進行顯示:

<html>
    <head>
        <style>
            body {
            background: white url(background.jpg);
            }
        </style>
    </head>
    <body>
        <img src='bar.png' width='800 height='600'></img>
    </body>
</html>      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

控制輸出分辨率

預設情況下,使用位圖圖檔的輸出時,Matplotlib 自動調節輸出的大小和分辨率。根據位圖圖檔的用途,我們也可以自己選擇分辨率。例如,如果圖檔是一張大海報的一部分,可能需要高分辨率,如果想生成縮略圖,那麼需要較低分辨率。

plt.savefig() 函數提供可選參數 dpi 控制輸出分辨率:

import numpy as np
import matplotlib.pyplot as plt
name_list = ('Omar', 'Serguey', 'Max', 'Zhou', 'Abidin')
value_list = np.random.randint(99, size=len(name_list))
pos_list = np.arange(len(name_list))
plt.bar(pos_list, value_list, alpha = .25, color = 'c', align = 'center')
plt.xticks(pos_list, name_list)
plt.savefig('bar_1.png', dpi = 300)      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

Tips:savefig() 函數的可選參數 dpi 控制以 DPI (每英寸點數)表示的圖檔分辨率。預設情況下,Matplotlib 将輸出 8 x 6 空間機關的圖形,即 4/3 的縱橫比。在 matplotlib 中,1 個空間機關等于 100 像素。是以,預設情況下,Matplotlib 提供 800 x 600 像素的圖檔檔案。如果我們使用 dpi=300,圖檔大小為 8*300 x 6*300,即 2400 x 1800 像素。

我們已經學習了如何控制圖形的縱橫比,如果将縱橫比和 DPI 結合起來,就可以完全控制圖檔的總體比例。例如,在 512 x 512 像素的圖檔中顯示六邊形。

import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(0, 2 * np.pi, 8)
points = np.vstack((np.cos(theta), np.sin(theta))).transpose()
plt.figure(figsize=(4., 4.))
plt.gca().add_patch(plt.Polygon(points, color = 'c'))
plt.grid(True)
plt.axis('scaled')
plt.savefig('polygon.png', dpi = 128)      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

上例中在 4 x 4 機關面積上顯示圖形,并以 128 dpi 的分辨率輸出,輸出将為 512 x 512 像素。我們還可以在 8 x 8 機關面積顯示 512 像素,但是要将分辨率變為 64 dpi:

import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(0, 2 * np.pi, 8)
points = np.vstack((np.cos(theta), np.sin(theta))).transpose()
plt.figure(figsize=(8., 8.))
plt.gca().add_patch(plt.Polygon(points, color = 'c'))
plt.grid(True)
plt.axis('scaled')
plt.savefig('polygon_1.png', dpi = 64)      
Matplotlib圖形的輸出與儲存前言生成PNG圖檔檔案控制透明度控制輸出分辨率生成PDF或SVG文檔

Tips:圖中注釋更小,網格線更細,這是由于注釋和線條的粗細都有自己的預設值,它們以空間機關表示。是以,将輸出分辨率除以 2 将使注釋變小兩倍。

生成PDF或SVG文檔

位圖圖檔将圖檔表示為一個給定比例的像素數組。放大後,将看到一些衆所周知的瑕疵(鋸齒、像素塊、模糊等)。而矢量圖像具有尺度不變性,無論以何種比例觀察它們,都不會導緻細節丢失。是以有時,我們需要矢量圖檔,Matplotlib 可以輸出 PDF、SVG 等矢量圖檔。

import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(-10, 10, 1024)
y = np.sinc(x)
plt.plot(x, y)
plt.savefig('sinc.pdf')      

Tips:調用 plt.savefig() 時,其中通過傳遞檔案名來指定檔案是 PNG、PDF 還是 SVG,Matplotlib 将通過檔案名的擴充名來推斷檔案類型。

在某些情況下,我們可能不希望顯式的聲明檔案的擴充名,我們可以通過 plt.savefig 的可選參數 format 來達到目标,例如通過設定 format='svg',plt.savefig 則不會從傳遞給函數的檔案名推斷輸出檔案類型,而是通過傳遞給格式的名稱。