В вашей ситуации наиболее простым было бы создать метки и интервалы вручную и применить это с помощью ax.xaxis.set_major_formatter
.
Вот возможное решение:
Поскольку ни один образец данных не был
Настройка:
# imports
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
# A dataframe with random numbers ro run tests on
np.random.seed(123456)
rows = 100
df = pd.DataFrame(np.random.randint(-10,10,size=(rows, 1)), columns=['error'])
datelist = pd.date_range(pd.datetime(2017, 1, 1).strftime('%Y-%m-%d'), periods=rows).tolist()
df['dates'] = datelist
df = df.set_index(['dates'])
df.index = pd.to_datetime(df.index)
test_df = df.copy(deep = True)
# Plot of data that mimics the structure of your dataset
ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar")
ax.figure.autofmt_xdate()
plt.figure(figsize=(15,8))
Возможное решение:
test_df = df.copy(deep = True)
ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar")
plt.figure(figsize=(15,8))
# Make a list of empty myLabels
myLabels = ['']*len(test_df.index)
# Set labels on every 20th element in myLabels
myLabels[::20] = [item.strftime('%Y - %m') for item in test_df.index[::20]]
ax.xaxis.set_major_formatter(ticker.FixedFormatter(myLabels))
plt.gcf().autofmt_xdate()
# Tilt the labels
plt.setp(ax.get_xticklabels(), rotation=30, fontsize=10)
plt.show()
Вы можете легко изменить форматирование меток, установив strftime.org
Соглашением для диапазонов является [inclusive, exclusive)
, то есть, если вы выполняете итерацию по диапазону [X,Y)
, вы концептуально выполните следующее (псевдокод):
for( iterator ii = X; ii != Y; ++ii) {
...
}
Это позволяет выразить пустой диапазон как [X,X)
. Кроме того, этот пустой диапазон отлично определен для каждого адреса, независимо от того, является ли он действительным или недействительным.
При этом требования к data()
(внимание мое):
23.3.6.4 [vector.data]
T * data () noexcept;
const T * data () const noexcept;
Возвраты: указатель, для которого [data (), data () + size ()) является допустимым диапазоном. Для непустого вектора data () == & amp; front ().
blockquote>Мне кажется, что единственная безусловная гарантия заключается в том, что
[data(),data() + size())
должен быть допустимым диапазоном. Для функцииsize() == 0
функция-членdata()
может возвращать любое значение, и диапазон будет действительным пустым диапазоном. Поэтому я бы сказал, что реализации разрешено возвращать ненулевой указатель, еслиsize()
равно нулю .
Существует состояние, в котором объект может быть действительным, но неопределенным:
действительное, но неуказанное состояние [§ 17.3]
состояние объекта, которое не указано, за исключением того, что инварианты объекта выполняются, и операции над объектом ведут себя так, как указано для его типа
[ Пример: Если объект x типа std :: vector находится в действительном, но неуказанном состоянии , x.empty () можно назвать безоговорочно, а x.front () можно вызвать только в том случае, если x.empty () возвращает false. -end example ]
blockquote>При чтении стандарта C ++ состояние
data()
не указывается, когда вектор пуст. Итак, состояние действительное, но неуказанное состояние . Поэтому возвращаемое значениеdata()
, когда вектор пуст, может быть любым (нулевое или случайное значение). Это зависит от реализации компилятора.В этом случае, следуя примеру в § 17.3, вы должны вызвать
empty()
перед использованиемdata()
, чтобы убедиться, что возвращаемое значение является вашим ожиданием.if (!v.empty()) do_something(v.data())
Да, это возможно, и libstdc ++ делает это. Вы можете посмотреть документацию data () в libstdc ++
data() _GLIBCXX_NOEXCEPT
{ return _M_data_ptr(this->_M_impl._M_start); }
Однако выполнение действий над этим указателем может не указываться, так как вы получаете доступ к не- инициализированный диапазон внутри вашего вектора, без его знаний (например, вы не знаете точный размер пакета памяти). Кроме того, поскольку size()
равно 0, ваш допустимый диапазон все еще пуст.
Ни одна из формулировок в стандарте не предлагает заданное значение для данных (), если вектор пуст ().
И вот какое-то окончательное доказательство того, почему вы не должны предполагать, что оно может быть равно нулю, даже хотя иногда это:
#include <vector>
#include <iostream>
void value_of_data(std::vector<int> const& v)
{
std::cout << "empty() = " << v.empty() << ", " << "data() = " << static_cast<const void*>(v.data()) << std::endl;
}
int main()
{
std::vector<int> v;
value_of_data(v);
v.resize(100, 0);
v.clear();
value_of_data(v);
}
пример вывода (gcc7.2, -O2, linux):
empty() = 1, data() = 0
empty() = 1, data() = 0x7ebc30