2015-10-26 61 views
0

我使用matplotlib 1.4.3python 3.3。我想繪製多個數字與多倍子圖。我現在面臨某種錯誤的那實在是無聊我:Matplotlib意外隱藏多邊形

When I use fill() and boxplot() methods whithin a figure, results of those functions are hidden if the figure is not the first one created.

這個bug似乎某種程度上與多邊形顯示和matplotlib環境狀態。

當解析只有一個單一的數字,一切工作正常。當我解析多個數字時,第一個就可以了。但是,在其他後續數字中,除了wiskerbox多邊形之外的所有內容都是隱藏的。

每個繪圖代碼都被封裝到一個函數中,該函數接受位置參數*args**kwargs。比方說簽名是:

def myplot(t, x, *args, *kwargs): 
    # [...] 
    hFig = plt.figure() 
    # [...] 
    return hFig 

據我瞭解python機制,函數調用得到解決後,必須有沒有活着的(我不使用全局變量),除了什麼matplotlib環境已經存儲到其全球命名空間變量

在每次調用中,我的圖爲close(),我也試過hFig.clf()此外在離開函數之前,卻沒有解決問題。

每個情節被包裹到打印機(裝飾)來添加通用功能:

def myprint(func): 
    def inner(*args, **kwargs) 
      # [...] 
      hFig = func(*args, **kwargs) 
      # [...] 
     return inner 

我迄今爲止嘗試:

  • 增加zscorewiskerbox多邊形,不加工;
  • 執行繪圖代不同線程,不工作;
  • 在不同進程中執行繪圖生成,但我必須更改我的函數簽名,因爲它可以被酸洗。

我不想使用dillpathos,即使我不會。

它看起來像是一個matplotlib環境錯誤,因爲當我運行不同的進程時,這個環境從頭開始重新創建,它的工作方式應該是這樣。我想知道是否有方法在python腳本中重置matplotlib環境狀態。如果不是,我能做些什麼來解決這個問題。

Obs .:我正在使用GridSpecs對象和subplot()方法來創建我的數字。當我計算自己的方框並使用add_axes()方法時,問題不存在。

更新:在這裏你可以找到我的問題的MCVE。通過這個簡單的例子,我發現了一個讓我的bug發生的行(看起來像我有舊的壞Matlab行爲)。看來plt.hold(False)改變了多邊形boxplot的顯示方式。而且,正如我指出的那樣,它與matplotlib全局名稱空間變量有關。我誤解了這種方法的工作方式,並在每個子流程中重置。

import datetime 
import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.gridspec as gspec 

def bloodyplotit(t_, x_): 
    hFig = plt.figure() 
    gs = gspec.GridSpec(1, 4, height_ratios=[1], width_ratios=[15, 2, 3, 1]) 
    gs.update(left=0.10, right=0.90, top=0.90, bottom=0.25, hspace=0.05, wspace=0.05) 
    plt.hold(True) 
    hAxe = plt.subplot(gs[0,0]) 
    hAxe.plot(t_, x_) 
    #plt.hold(False) # <------------------------ This line make the scirpt bug 
    hAxe = plt.subplot(gs[0,1]) 
    hAxe.hist(x_, orientation='horizontal') 
    hAxe = plt.subplot(gs[0,3]) 
    hAxe.boxplot(x_) 
    plt.show() 


n = 1000 
t = datetime.datetime.utcnow() + np.arange(n)*datetime.timedelta(minutes=1) 
x = np.random.randn(1000,1) 

for i in range(10): 
    bloodyplotit(t, x) 
+0

你可以減少你的問題到[MCVE](http://stackoverflow.com/help/MCVE)嗎? – tom

+0

今天下午我會這麼做 – jlandercy

回答

1

這裏是甚至更小腳本產生錯誤:

x = np.random.randn(1000) 
fig, ax = plt.subplots(1, 2) 
ax[0].hold(True) 
ax[0].boxplot(x); 
ax[1].hold(False) 
ax[1].boxplot(x); 

enter image description here

據我所知,這是預期的行爲。據的plt.hold文檔,

When hold is True, subsequent plot commands will be added to the current axes. When hold is False, the current axes and figure will be cleared on the next plot command.

箱線圖是一個複合對象:它是通過調用多個繪圖命令產生。如果hold爲False,則在每個命令之間清除座標軸,因此boxplot的部分不顯示。

就我個人而言,我從來沒有找到理由在使用matplotlib的10多年中切換保持狀態。我的經驗是,做(特別是全球)只會造成混亂,我建議避免它。

+0

是的這就是我想到的,正如我所說我正在用我的Matlab背景思考 – jlandercy

+0

順便說一下,你能解釋一下如何將多個圖形收集到單個座標軸中,而不將保持屬性設置爲True ? – jlandercy

+0

默認情況下保持爲真。只要你從來沒有把它設置爲假,你應該沒問題。 – jakevdp