2015-10-26 4 views
0

Я использую matplotlib 1.4.3 с python 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.

Эта ошибка, кажется, так или иначе связанного с полигона отображения и 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 

То, что я пытался до сих пор:

  • Увеличение zscore из wiskerbox и многоугольники, не за работой;
  • Выполнение генерации участка в разных нит., не работает;
  • Выполнение построения участка в разных процессах , но я должен изменить свою подпись функции, потому что ее можно мариновать.

Я не хочу использовать dill и pathos, даже если бы я не могу.

Похоже, это ошибка окружения matplotlib, потому что, когда я запускаю разные процессы, эта среда воссоздается с нуля, и она работает так, как должна. Я хотел бы знать, есть ли способ сбросить состояние среды matplotlib в сценарий python. Если нет, что я могу сделать для решения этой проблемы.

Обс .: Я использую объект GridSpecs и метод subplot() для создания фигур. Проблема не возникала, когда я сам вычислял ящики и использовал метод add_axes().

Обновление: Здесь вы можете найти MCVE моей проблемы.Сделав этот простой пример, я нашел строку, из-за которой произошел мой баг (похоже, у меня старые плохие поведения 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.

Boxplot является составным объектом: он создается путем вызова нескольких команд печати. Если удержание False, оси очищаются между каждой из этих команд, поэтому части ящика не отображаются.

Лично я никогда не находил причины переключать состояние удержания через 10 лет использования matplotlib. Мой опыт заключается в том, что выполнение этого (особенно в глобальном масштабе) просто вызывает путаницу, и я бы рекомендовал избежать этого.

+0

Да, это то, что я выяснил, так как я сказал, что думал с моим фоном Matlab – jlandercy

+0

Кстати, не могли бы вы объяснить, как вы собираете несколько графиков в одну ось без установки свойств удержания на True ? – jlandercy

+0

Удержание по умолчанию равно True. До тех пор, пока вы не установите его в False, вы должны быть в порядке. – jakevdp

Смежные вопросы