Следующий код должен отображать смещение «ax» вправо (перекрывающееся «ax1») с дополнением слева (там, где оно было изначально).
# Implementation of matplotlib function
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LogNorm
Z = np.random.rand(6, 30)
fig, (ax, ax1) = plt.subplots(1, 2)
ax.pcolor(Z)
ax1.pcolor(Z)
chartBox = ax.get_position()
ax.set_position([chartBox.x0 + chartBox.width / 2,
chartBox.y0,
chartBox.width,
chartBox.height])
ax.set_title("Original Window")
ax1.set_title("Modified Window")
plt.show()
Однако в блокноте Jupyter (проверено на vscode и colab) левое пустое пространство обрезано, но при запуске сценария в файле .py оно отображается правильно. Как я могу решить эту проблему?
Оба протестированы на версии Python 3.12 в vscode (jupyterlab==4.1.6) и в терминале с matplotlib==3.8.4. Изменение plt.show() на plt.savefig() приводит к появлению пустого места слева (даже внутри записной книжки). Я подозреваю, что рендеринг из записной книжки неисправен, но я не знаю точных настроек.
Вот что отображает блокнот Jupyter:
Вот что отображает тот же код, запущенный в файле сценария .py:
Контекст
Я перебирал некоторые данные и хотел отобразить несколько графиков 2 на 2, при нечетном сочетании я хотел отобразить один график по центру и отключить второй пустой график. Идея заключалась в том, чтобы использовать .subplots(nrows=1,ncols=2) (потому что у меня не было другой идеи) и сместить первый участок вправо с помощью ax.set_position(). Как оказалось, это не сработало.
<продолжение> примерно на уровне значения 20 на подграфике «Исходное окно». График «Исходное окно» остается привязанным к левой границе независимо от того, включаю ли я часть ax.set_position() или нет. Что касается «Идея заключалась в том, чтобы использовать .subplots(nrows=1,ncols=2) (потому что у меня не было другой идеи) и сместить первый график вправо с помощью ax.set_position()». Это само определение XY-проблема, которую вы создали. Возможно, вы на правильном пути; однако, что вы на самом деле пытаетесь здесь решить. Проблема, о которой вы писали до предпоследнего предложения? Или ...
<продолжение> Какова, по вашему мнению, была ваша первоначальная цель? А пока вы можете просто уточнить в комментариях, чтобы мы обращались к правильному вопросу. Честно говоря, на данный момент я не знаю, были ли вы на правильном пути или нет, используя тот подход, который вы пробуете. Но если настоящая цель — «Идея», то я не буду стараться максимально придерживаться того, что у вас есть, и не рассматривать другие подходы.
Это правда, что я хочу сделать X (иметь центрированный график по горизонтали), а не Y (чтобы левое пустое пространство не было обрезано блокнотом Jupyter), однако после непродолжительного поиска в Google я не нашел никого, обращающегося к Y, и я подумал что я был настолько разочарован попыткой Y, что стоило выслушать сообщество по этому вопросу, потому что я предполагал, что кто-то в обозримом будущем наткнется на Y и найдет это полезным.
@Уэйн, я добавил некоторую информацию, но «сюжет «Исходное окно» остается привязанным к левой границе, независимо от того, включаю ли я часть ax.set_position() или нет». у вас есть эта проблема даже при запуске файла .py?
Да, когда я запускаю его как Python, он тоже остается слева. Однако я на 100% уверен, что оба используют один и тот же Python и пакеты в моей системе. Я в этом не уверен, учитывая, что вы видите разные результаты. Или, может быть, это связано с тем, что в вашей системе серверная часть отличается от Python в командной строке и в Jupyter? (На самом деле вы не указываете, в каком бэкэнде вы его видите, когда запускаете его как скрипт Python.) В моем случае я разрешаю ему сохранять только рисунок графика, потому что нет другого выбора для графического бэкэнда, над которым я работаю. облако в настоящее время.
Серверной частью графического пользовательского интерфейса является TkAgg, а серверной частью savefig() является значение по умолчанию (то есть agg согласно документации). На моей стороне оба показывают пустое место слева (даже при вызове plt.savefig() из записной книжки). Так что очень странно, что у вас другое поведение
«даже при вызове plt.savefig() из записной книжки» О, если я правильно понимаю, это, похоже, исключает мое предположение, что это разные версии. Итак, когда вы запускаете код, вы видите, что он привязан к левой стороне вывода блокнота, но при использовании plt.savefig() в том же блокноте он добавляет отступы?
Да, именно, во всех случаях есть отступ, за исключением использования plt.show() внутри блокнота, где он прикрепляется к левой стороне окна. Я не совсем понимаю, почему у вас нет отступа даже при звонке plt.savefig(). Потому что я предполагаю, что проблема в том, как блокнот Jupyter отображает matplotlib, но ваш случай подсказывает мне, что это может быть что-то другое.
Теперь я получил хорошее преимущество в том, что прокладка не отображается. Я опубликовал ответ, поскольку он довольно сложен и требует кода. Кроме того, я смотрю на то, что получаю от plt.savefig(), и слева от «исходного окна» есть отступы. Что касается вашей последней части комментария: «Я не совсем понимаю, почему у вас нет отступов даже при вызове plt.savefig()». Я тогда не видел вашего обновленного сообщения и понял, что это отрезание отступов. Я вижу прокладку. В своих первых двух постах я был сосредоточен на движении двух графиков и не осознавал, что отступы — это то, что вам тоже нужно. Извини.
Надеюсь, это то, что вам нужно для достижения вашей настоящей цели. Возможно, вы захотите проверить здесь просто чтобы рассмотреть другие способы управления макетом, помимо подзаголовка. Плюс есть здесь , здесь и здесь.






В наши дни, если вы ничего не указываете, то %matplotlib inline — это серверная часть по умолчанию. А встроенное значение по умолчанию для bbox_inches в наши дни — tight. Я вернусь к этому через минуту. Итак, один из вариантов - сделать это не inline. Если вы перейдете сюда и щелкните значок «launch binder» (значки внизу позволяют выбрать конкретную версию Jupyter), вы получите сеанс, в котором ipympl установлен с современными версиями Jupyter. Таким образом, вы можете добавить %matplotlib ipympl в качестве первой строки вверху кода, который затем вставите в новую ячейку, запустите ее и увидите, что теперь есть отступы. (Если у вас еще не установлен ipympl, вам нужно сначала установить его и правильно обновить/перезапустить все, чтобы использовать его в качестве серверной части. Некоторые говорят, что обновления страницы браузера достаточно; однако я бы предложил перезапустить все [браузер , Jupyter и ваша машина], если можете, поскольку это добавляет множество возможностей на многих уровнях вашей технологии.)
Вы можете убедиться, что это удалось, перезапустив ядро и добавив # перед %matplotlib ipympl, чтобы прокомментировать первую строку, и перезапустить код. Он должен вернуться во встроенный режим с bbox_inches как tight, чтобы крайний левый график придерживался левой границы.
bbox_inches='tight'Поскольку при встроенной настройке bbox_inches по умолчанию используется как tight, вы можете продолжать использовать встроенный бэкэнд; однако настройте его так, чтобы он не был установлен на tight.
Итак, в своем блокноте создайте новую ячейку и выполните следующее:
%config InlineBackend.print_figure_kwargs = {'bbox_inches':None}`
После этого попробуйте исходный блок кода как есть, и теперь вы должны увидеть отступы.
Атрибуция:
На основании комментариев и нижней части этого ответа там же , где конкретно упоминается «встроенный бэкэнд» и этого ответа здесь на вопрос «Как отключить bbox_inches='tight» при работе со встроенным matplotlib в блокнот ipython'
%matplotlib ipympl требует pip install ipympl, но plt.show() возвращает ошибку javascript, где написано «Ошибка: ни одна версия модуля jupyter-matplotlib не зарегистрирована». Он запросил загрузить какой-то пакет. А трассировка стека показывает ссылки вдоль линии *.vscode-resource.vscode-cdn.net. Поэтому я считаю, что проблема в том, что vscode не находит сторонний виджет. Он работает в colab (хотя вам нужно добавить from google.colab import output; output.enable_custom_widget_manager()). В качестве альтернативы ваш второй подход работает как в colab, так и в vscode. Вы молодцы!
Да, я обновил, чтобы упомянуть, что если у вас его нет, вам нужно его установить. Я упоминаю, куда я послал вас, чтобы оно было установлено. Однако я не вижу этой ошибки и поэтому не думаю, что вы еще должным образом обновили все после установки. То, с чем вы столкнулись, похоже на мой обмен мнениями из этого пункта в некоторых связанных комментариях и далее. Вы увидите, что обновление/перезапуск было галочкой. Я думаю, что вы попадаете в это.
да, действительно, мне пришлось перезапустить vscode, или, может быть, это были какие-то проблемы с Интернетом.
Я не думаю, что это был Интернет. ipympl многое добавляет, поэтому обновления в настройках и изменениях необходимо полностью распространять. Я тоже попытался уточнить это в ответе. Настройка bbox_inches проще; однако знание ipympl поможет большему количеству людей в современном использовании Jupyter в наши дни, учитывая, что поздние версии JupyterLab 3 и выше, а также Jupyter Notebook 7+ сейчас нуждаются в нем для многих вещей.
«но при запуске сценария в файле .py он отображает его правильно». Возможно, это так; однако вы не указываете, какая версия Python и задействованные пакеты используются в случае, если вы запускаете его как сценарий, а не в Jupyter. Окружающая среда, вероятно, другая и поможет решить вашу проблему. Когда я запускаю его в Jupyter, а затем как скрипт на том же Python, где я сохраняю файл, используя
plt.savefig("test_fig.png")вместоplt.show(), я вижу то же самое. А именно, ось «Модифицированное окно» переместилась влево, так что она перекрывает «Исходное окно»....