Ошибка форматирования оси matplotlib при переходе с версии 0.99.1.1 на версию 1.2.x - PullRequest
1 голос
/ 30 марта 2012

Сценарий python, который я написал некоторое время назад, неожиданно перестал работать, после того как я обновил свою библиотеку matplotlib с версии '0.99.1.1' до версии '1.2.x'.

Я использую python v 2.6.5

После нескольких часов отладки я наконец нашел строки, которые вызывали проблему.это следующие две строки:

# Note: ax is an Axis type, phist is an iterable type
def function_no_longer_works(phist):
    # some code before ...
    ax.xaxis.set_major_locator(_MajorLocator(phist))
    ax.xaxis.set_major_formatter( FuncFormatter(_MajorFormatter(phist).format)
    # some code after ...



class _CanFit(object):
    def __init__(self, phist):
        self.phist = phist

    def weeks(self):
        if (self.phist[-1].date - self.phist[0].date).days > 5*30:
            # 5 months at most
            return False
        return True

    def months(self):
        if (self.phist[-1].date - self.phist[0].date).days > 3*365:
            # 3 years at most
            return False
        return True


class _MajorLocator(object):
    """calculates the positions of months or years on the y-axis

    These positions will be where the major ticks and labels for them are.
    If months can't fit, there are no major ticks, only minor ticks.

    """
    def __init__(self, phist):
        self.phist = phist

    def set_axis(self, axis): pass
    def view_limits(self, start, stop): pass

    def __call__(self):
        """returns an iterable of all the months or years on the y-axis"""
        can_fit = _CanFit(self.phist)
        major_ticks = []
        if can_fit.weeks():
            month = None
            # step through the price history list and find the index of every
            # point where the previous point has a different month
            for (i, p) in enumerate(self.phist):
                if month != p.date.month:
                    if month is not None:
                        major_ticks.append(i)
                    month = p.date.month
        elif can_fit.months():
            year = None
            # same as above, but for years.
            for (i, p) in enumerate(self.phist):
                if year != p.date.year:
                    if year is not None:
                        major_ticks.append(i)
                    year = p.date.year
        return major_ticks



class _MajorFormatter(object):
    """Formats the major ticks as years or months"""
    def __init__(self, phist):
        self.phist = phist

    def format(self, x, pos=None):
        can_fit = _CanFit(self.phist)
        if can_fit.weeks():
            # Jan Feb Mar etc
            return self.phist[x].date.strftime("%b") 
        if can_fit.months():
            # 90, 91, etc
            return self.phist[x].date.strftime("%y")

Вот трассировка стека, когда я запускаю скрипт с matplot lib v 1.2.x:

/usr/local/lib/python2.6/dist-packages/matplotlib/axes.pyc in plot(self, *args, **kwargs)
   3851 
   3852 
-> 3853         self.autoscale_view(scalex=scalex, scaley=scaley)
   3854         return lines
   3855 

/usr/local/lib/python2.6/dist-packages/matplotlib/axes.pyc in autoscale_view(self, tight, scalex, scaley)
   1840                 x1 += delta
   1841             if not _tight:
-> 1842                 x0, x1 = xlocator.view_limits(x0, x1)
   1843             self.set_xbound(x0, x1)
   1844 

TypeError: 'NoneType' object is not iterable

У меня закончились идеи послеломая себе голову последние несколько дней.Буду очень признателен за любую помощь в решении этой проблемы.

1 Ответ

0 голосов
/ 02 апреля 2012

Ваша проблема в том, что вы ничего не возвращаете в _MajorLocator.view_limits.

Ожидается реализация некоторого метода автоматического масштабирования с view_limits. Вы можете просто вернуть start и stop, если вам все равно.

Однако вам, вероятно, следует создавать подклассы matplotlib.ticker.AutoLocator (или другой класс локатора), а не начинать с нуля.

В противном случае вам потребуется повторно реализовать метод view_limits, если вы хотите использовать автоматическое масштабирование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...