Annotate seaborn distplot с логарифмической шкалой выдает ошибку - PullRequest
2 голосов
/ 23 марта 2019
%matplotlib inline
import seaborn as sns
titanic = sns.load_dataset('titanic')
ax1 = sns.distplot(titanic['fare'], kde=False, bins=15,)

# ax1.set_yscale('log')

for p in ax1.patches:
    ax1.annotate(
        s=f"{p.get_height():1.0f}",
        xy=(p.get_x() + p.get_width() / 2., p.get_height()), 
        xycoords='data',
        ha='center', 
        va='center', 
        fontsize=11, 
        color='black',
        xytext=(0,7), 
        textcoords='offset points',
    )

Приведенный выше код отображает гистограмму для Fare титанового набора данных, где каждый столбец имеет свое значение с использованием ax1.annotate. Проблема возникает, когда я хочу установить для шкалы y значение logc - раскомментируйте строку set_yscale и запустите ее; выдает ошибку, говорящую:

ValueError: Размер изображения 378x84035 пикселей слишком велик. Оно должно быть меньше 2 ^ 16 в каждом направлении.

Возможно, параметр xycoords следует изменить, но я не совсем уверен, что его изменить тоже.

Я на Python 3.7.2, версия seaborn 0.9.0. Matplotlib версии 3.0.2, и я использую встроенный бэкэнд.

1 Ответ

3 голосов
/ 24 марта 2019

Некоторые аннотации размещены на y=0.Это приведет к тому, что положение будет неопределенным в логарифмическом масштабе.
В блокноте jupyter со встроенным бэкэндом по умолчанию для показа фигур используется прогон их через параметр bbox_inches="tight", равный savefig.Этот «жесткий» алгоритм в таком случае не может найти метки и в любом случае увеличит размер фигуры, чтобы включить их.

Решение, которое я предлагаю здесь, состоит в том, чтобы установить опцию clip_on для аннотаций на True.Это предотвратит видимость аннотаций вне осей.Тем самым он решает проблему аннотаций с нулевым разложением в логарифмическом масштабе.

import matplotlib.pyplot as plt
import seaborn as sns
titanic = sns.load_dataset('titanic')
ax1 = sns.distplot(titanic['fare'], kde=False, bins=15,)

ax1.set_yscale('log')

for p in ax1.patches:
    ax1.annotate(
        s=f"{p.get_height():1.0f}",
        xy=(p.get_x() + p.get_width() / 2., p.get_height()), 
        xycoords='data',
        ha='center', 
        va='center', 
        fontsize=11, 
        color='black',
        xytext=(0,7), 
        textcoords='offset points',
        clip_on=True,                   # <---  important
    )

plt.savefig("outfig.png", bbox_inches="tight")
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...