matplotlib: настроенные тики по оси x для cdf значений даты и времени

У меня есть cdf списка datetime. После запуска следующего кода, где objDate — это список значений даты и времени (формат: %Y-%m-%d), я получаю cdf с галочками на оси x, показывающими каждый второй год в диапазоне значений. Как я могу настроить метки для делений по оси X, указав:

1. диапазон (мин. год и макс. год)
2. интервал (скажем, 6 месяцев друг от друга, чтобы метки делений как 17/01, 17/07, 18/01, 18/07, ... )

import matplotlib.pyplot as plt
import pandas as pd

ser = pd.Series(objDate)
ser.hist(cumulative=True, density=1, bins=500, histtype='step')
plt.show()

person SaadH    schedule 04.06.2018    source источник
comment
пожалуйста, предоставьте образцы данных и какой график вы получите.   -  person user59271    schedule 04.06.2018


Ответы (1)


Что касается второго вопроса, вы можете использовать matplotlib.dates локаторы и средства форматирования. Они отлично работают в случае hist.

import matplotlib.pyplot as plt
plt.rcParams['axes.axisbelow'] = True
import matplotlib.dates as dates
import numpy as np; np.random.seed(42)
import pandas as pd

objDate = dates.num2date(np.random.normal(735700, 300, 700))

ser = pd.Series(objDate)
ax = ser.hist(cumulative=True, density=1, bins=500, histtype='step', linewidth=2)

ax.xaxis.set_major_locator(dates.MonthLocator([1,7]))
ax.xaxis.set_major_formatter(dates.DateFormatter("%m/%y"))
plt.setp(ax.get_xticklabels(), rotation=60)

plt.show()

введите здесь описание изображения

Для первого вопроса это непросто, потому что matplotlib всегда предполагает, что вся ось отмечена галочкой. Решением было бы создать подкласс используемого локатора и позволить ему принимать ограничительные аргументы.

from datetime import datetime
import matplotlib.pyplot as plt
plt.rcParams['axes.axisbelow'] = True
import matplotlib.dates as dates
import numpy as np; np.random.seed(42)
import pandas as pd

objDate = dates.num2date(np.random.normal(735700, 300, 700))

ser = pd.Series(objDate)
ax = ser.hist(cumulative=True, density=1, bins=500, histtype='step', linewidth=2)


class RestrictedLocator(dates.MonthLocator):
    def __init__(self, dmin=None, dmax=None, **kw):
        self.dmin = dmin
        self.dmax = dmax
        dates.MonthLocator.__init__(self, **kw)

    def __call__(self):
        try:
            dmin, dmax = self.viewlim_to_dt()
        except ValueError:
            return []

        self.dmin = self.dmin.replace(tzinfo=dmin.tzinfo)
        self.dmax = self.dmax.replace(tzinfo=dmin.tzinfo)
        dmin = np.max([dmin, self.dmin])
        dmax = np.min([dmax, self.dmax])
        return self.tick_values(dmin, dmax)


loc = RestrictedLocator(dmin=datetime(2015,1,1), 
                        dmax = datetime(2017,12,31),
                        bymonth=[1,7])

ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(dates.DateFormatter("%m/%y"))
plt.setp(ax.get_xticklabels(), rotation=60)

plt.show()

введите здесь описание изображения

person ImportanceOfBeingErnest    schedule 04.06.2018
comment
очень полезно :) Хотя это отдельный вопрос, есть идеи, как можно убрать вертикальную черту в конце графика? Это как-то связано с баками. - person SaadH; 05.06.2018
comment
Что-то вроде этого? - person ImportanceOfBeingErnest; 05.06.2018
comment
Да, но их подход не работает со значениями даты и времени, bins = sorted(X) + [np.inf] дает TypeError: can't compare datetime.datetime to float - person SaadH; 05.06.2018
comment
Тогда я предлагаю вам задать отдельный вопрос, сославшись на тот, который не работает, и предоставить минимальный воспроизводимый пример. - person ImportanceOfBeingErnest; 05.06.2018