Python量化交易基礎講堂-Matplotlib常見問題解決

歡迎你們訂閱《Python實戰-構建基於股票的量化交易系統》小冊子,小冊子會陸續推出與小冊內容相關的專欄文章,對涉及到的知識點進行更全面的擴展介紹。python

本次專欄主要介紹下小冊子中使用Matplotlib庫時所涉及到的一些問題。最多見的是「中文顯示亂碼問題」和「tight_layout()出錯問題」。bash

中文顯示亂碼問題

因爲Matplotlib庫缺乏中文字體,所以在圖表上顯示中文時會出現亂碼。一種解決方法爲在代碼中添加如下參數設置,以下所示:微信

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.figure import Figure

# 正常顯示畫圖時出現的中文和負號
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False

# 如下是其餘代碼
複製代碼

另外一種方法是更改配置文件。這裏咱們以mac系統爲例來介紹下。在MAC中調試matplotlib時中文顯示框框解決方法:markdown

  • 下載simhei.ttf字體庫拷貝至matplotlib字體文件夾(Macintosh HD ▸ 用戶 ▸ xxxx ▸ anaconda3 ▸ lib ▸ python3.7 ▸ site-packages ▸ matplotlib ▸ mpl-data ▸ fonts▸ ttf)。dom

  • 一樣在matplotlib/mpl-data/fonts目錄下面修改配置文件matplotlibrcsocket

font.family : sans-serif
font.sans-serif : SimHei, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif axes.unicode_minus:False 
複製代碼
  • 三、在Python中運行以下代碼從新加載字體使配置生效:
from matplotlib.font_manager import _rebuild
_rebuild() #reload 
複製代碼

tight_layout()出錯問題

在matplotlib中,軸Axes的位置以標準化圖形座標指定,可能發生的狀況是軸標籤、標題、刻度標籤等等會超出圖形區域,致使顯示不全。Matplotlib v1.1 引入了一個新的命令tight_layout(),做用是自動調整子圖參數,使之填充整個圖像區域。 調用plt.show()函數時會自動運行tight_layout()函數,以下所示:函數

def show(self):
    self.figure.tight_layout()
    FigureCanvasAgg.draw(self)
    if PORT is None:
        return

    if matplotlib.__version__ < '1.2':
        buffer = self.tostring_rgb(0, 0)
    else:
        buffer = self.tostring_rgb()

    if len(set(buffer)) <= 1:
        # do not plot empty
        return

    render = self.get_renderer()
    width = int(render.width)

    plot_index = index if os.getenv("PYCHARM_MATPLOTLIB_INTERACTIVE", False) else -1
    try:
        sock = socket.socket()
        sock.connect((HOST, PORT))
        sock.send(struct.pack('>i', width))
        sock.send(struct.pack('>i', plot_index))
        sock.send(struct.pack('>i', len(buffer)))
        sock.send(buffer)
    except OSError as _:
        # nothing bad. It just means, that our tool window doesn't run yet
        pass
複製代碼

咱們經過如下一個例程來介紹,最終的顯示效果以下所示:字體

fig = plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
ax1.plot(np.arange(10), np.random.randint(0, 10, 10), ls='-', c='r', lw=1)
ax2.plot(np.arange(10), np.random.randint(10, 20, 10), ls='-', c='y', lw=1)
plt.show()

複製代碼

不過不少時候會出現tight_layout()不工做的狀況,好比出現如下提示: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect. warnings.warn("This figure includes Axes that are not compatible "ui

這個警告的緣由是tight_layout這個函數出錯了,警告語句出現的緣由時axes列表爲空,tight_layout()中相應的代碼,以下所示:spa

subplotspec_list = get_subplotspec_list(self.axes)
if None in subplotspec_list:
    cbook._warn_external("This figure includes Axes that are not "
                         "compatible with tight_layout, so results "
                         "might be incorrect.")
複製代碼

可見這個函數並不太穩定。tight_layout不起做用的時候,繪圖效果以下所示,可見子圖並無填充整個圖像區域。

網上搜索了下發現也有相似的狀況出現,附上部分案例的截圖:

接下來咱們嘗試下解決方法,tight_layout在plt.savefig的調用方式相對比較穩定,咱們將plt.show()函數替換爲plt.savefig函數,替換後會在本地另外爲png圖片,該圖片中子圖填充了整個圖像區域。

plt.savefig('fig.png', bbox_inches='tight') # 替換 plt.show()

購買小冊子的同窗注意了:咱們會把這篇專欄的鏈家附加到《前置基礎:Matplotlib函數式繪圖的方式》這一節內容中。

更多的量化交易內容歡迎你們訂閱小冊閱讀!!同時也歡迎你們關注個人微信公衆號【元宵大師帶你用Python量化交易】瞭解更多Python量化交易相關內容

相關文章
相關標籤/搜索