Остановить метки оси X от сжатия графика в Matplotlib? - PullRequest
0 голосов
/ 23 сентября 2018

Я пытаюсь сделать гистограмму со следующим кодом:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

test = {'names':['a','b','abcdefghijklmnopqrstuvwxyz123456789012345678901234567890'], 'values':[1,2,3]}
df = pd.DataFrame(test)

plt.rcParams['figure.autolayout'] = False
ax = sns.barplot(x='names', y='values', data=df)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
plt.show()

Но я получаю следующую ошибку, потому что длинное значение в «names» в качестве метки на оси x делаетизображение уменьшается до тех пор, пока нижняя часть не окажется над верхней частью.

Traceback (most recent call last):
  File "C:/Users/Adam/.PyCharm2018.2/config/scratches/scratch.py", line 11, in <module>
    plt.show()
  File "C:\Anaconda3\lib\site-packages\matplotlib\pyplot.py", line 253, in show
    return _show(*args, **kw)
  File "C:\Program Files\JetBrains\PyCharm 2018.2.3\helpers\pycharm_matplotlib_backend\backend_interagg.py", line 25, in __call__
    manager.show(**kwargs)
  File "C:\Program Files\JetBrains\PyCharm 2018.2.3\helpers\pycharm_matplotlib_backend\backend_interagg.py", line 107, in show
    self.canvas.show()
  File "C:\Program Files\JetBrains\PyCharm 2018.2.3\helpers\pycharm_matplotlib_backend\backend_interagg.py", line 62, in show
    self.figure.tight_layout()
  File "C:\Anaconda3\lib\site-packages\matplotlib\figure.py", line 2276, in tight_layout
    self.subplots_adjust(**kwargs)
  File "C:\Anaconda3\lib\site-packages\matplotlib\figure.py", line 2088, in subplots_adjust
    self.subplotpars.update(*args, **kwargs)
  File "C:\Anaconda3\lib\site-packages\matplotlib\figure.py", line 245, in update
    raise ValueError('bottom cannot be >= top')
ValueError: bottom cannot be >= top

Вот как это выглядит, если я немного уменьшу длину этого имени: enter image description here

Как я могу заставить его расширять фигуру, чтобы она соответствовала метке, а не сжимать оси?

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Если вы хотите это в интерактивном бэкэнде, я не нашел другого способа, кроме как вручную настроить размер фигуры.Вот что я получаю, используя qt5agg backend:

ax = sns.barplot(x='names', y='values', data=df)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
ax.figure.set_size_inches(5, 8)  # manually adjust figure size
plt.tight_layout()  # automatically adjust elements inside the figure
plt.show()

enter image description here

Обратите внимание, что научный режим Pycharm может творить магию, которая не позволяет этомуработать, поэтому вам может потребоваться деактивировать его или просто запустить скрипт вне pycharm.

0 голосов
/ 23 сентября 2018

Один из обходных путей - создать экземпляр Axes самостоятельно как оси , а не как вспомогательный участок.Тогда tight_layout() не имеет никакого эффекта, даже если он вызывается изнутри.Затем вы можете передать Axes с ключевым словом ax в sns.barplot.Теперь проблема в том, что если вы звоните plt.show(), метка может быть обрезана, но если вы звоните savefig с bbox_inches='tight', размер рисунка будет расширен, чтобы он содержал как фигуру, так и все метки:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

fig = plt.figure()
ax = fig.add_axes([0,0,1,1])

test = {'names':['a','b','abcdefghijklmnopqrstuvwxyz123456789012345678901234567890'], 'values':[1,2,3]}
df = pd.DataFrame(test)

#plt.rcParams['figure.autolayout'] = False
ax = sns.barplot(x='names', y='values', data=df, ax=ax)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
#plt.show()
fig.savefig('long_label.png', bbox_inches='tight')

ПРЕДУПРЕЖДЕНИЕ: у меня нет pycharm, поэтому в этом коде предполагается, что matplotlib ведет себя одинаково с pycharm и без него.В любом случае, для меня результат выглядит так:

result of above code

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