Python pandas изображает смещение оси абсцисс, если двойка двух осей ординат
У меня есть датафрейм с 3 столбцами: один из них - столбец "groupby", два других - "нормальные" столбцы со значениями. Я хочу создать коробочную диаграмму и гистограмму. На гистограмме я хочу визуализировать количество вхождений элемента каждой группы. Позвольте моему примеру кода рассказать об этом кадре более подробно:
li_str = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
df = pd.DataFrame([[i]+j[k] for i,j in {li_str[i]:np.random.randn(j, 2).tolist() for i,j in \
enumerate(np.random.randint(5, 15, len(li_str)))}.items() for k in range(len(j))]
, columns=['A', 'B', 'C'])
Итак, выше я генерирую случайное количество случайных значений для каждого элемента в li_str
и я делаю это для столбцов B
а также C
,
Тогда я визуализирую только коробочный сюжет:
fig, ax = plt.subplots(figsize=(16,6))
p1 = df.boxplot(ax=ax, column='B', by='A', sym='')
Теперь я визуализирую количество элементов в каждой группе (поэтому случайные числа, которые я сгенерировал выше с np.random.randint(5, 15, len(li_str))
код):
fig, ax = plt.subplots(figsize=(16,6))
df_gb = df.groupby('A').count()
p2 = df_gb['B'].plot(ax=ax, kind='bar', figsize=(16,6), colormap='Set2', alpha=0.3)
plt.ylim([0, 20])
И теперь я хочу эти два в одной диаграмме:
fig, ax = plt.subplots(figsize=(16,6))
ax2 = ax.twinx()
df_gb = df.groupby('A').count()
p1 = df.boxplot(ax=ax, column='B', by='A', sym='')
p2 = df_gb['B'].plot(ax=ax2, kind='bar', figsize=(16,6)
, colormap='Set2', alpha=0.3, secondary_y=True)
plt.ylim([0, 20])
Кто-нибудь знает, почему мое поле смещено вправо с помощью одного тика оси X? Я использую Python 3.5.1, pandas 0.17.0, matplotlib 1.4.3
Спасибо!!!
1 ответ
Это связано с тем, что блокпост и гистограмма не используют одинаковые символы, даже если метки совпадают.
df.boxplot(column='B', by='A')
plt.xticks()
(array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), <a list of 10 Text xticklabel objects>)
df.groupby('A').count()['B'].plot(kind='bar')
plt.xticks()
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), <a list of 10 Text xticklabel objects>)
На первый взгляд это выглядит как несоответствие, которое должно быть исправлено в matplotlib boxplot()
, но я мог бы просто пропустить обоснование.
В качестве обходного пути используйте matplotlib bar()
, это позволяет вам указать xticks, чтобы соответствовать тем из boxplot (я не нашел способ сделать это с df.plot(kind='bar')
,
df.boxplot(column='B', by='A')
plt.twinx()
plt.bar(left=plt.xticks()[0], height=df.groupby('A').count()['B'],
align='center', alpha=0.3)