2025, Nov 11 12:03
Как сделать перенос строки в LaTeX-подписях Plotly в Python
Почему не работает перенос строки в LaTeX подписях Plotly и как его сделать: экранирование в Python, единый математический блок, матрица для α и β. Экспорт OK.
Аккуратно перенести строку в тексте математического режима в Plotly оказывается неожиданно непросто. На первый взгляд это выглядит как обычная задача LaTeX, но на деле сходятся сразу три слоя: экранирование строк в Python, правила разбора LaTeX в Plotly и ограничения математического режима LaTeX. Если исправить только один из этих уровней, ничего не заработает. Ниже — практическое объяснение с примерами сбоев и рабочий способ расположить символы вроде α и β на разных строках.
Проблема на примере кода
Ниже минимальный пример, в котором пробуются разные варианты переноса строки между α и β. Ни один не срабатывает — у каждого своя причина.
import plotly.graph_objects as gobj
canvas = gobj.Figure()
canvas.add_trace(gobj.Box(y=[10, 14]))
canvas.update_layout(xaxis_title="$\alpha \\ \beta$") # вызывает ошибку to_image
# canvas.update_layout(xaxis_title=r"$\alpha \\ \beta$") # нет переноса между символами alpha и beta в математическом режиме
# canvas.update_layout(xaxis_title="$\alpha$<br>$\beta$") # отображается только математический символ alpha, а beta вообще нет!
# canvas.update_layout(xaxis_title="$\alpha \\ \beta$") # нет переноса между символами alpha и beta в математическом режиме
# canvas.update_layout(xaxis_title="$$\alpha \\ \beta$$") # нет переноса между символами alpha и beta в математическом режиме
# canvas.update_layout(xaxis_title="$$\alpha$$ <br> $$\beta$$") # отображается только математический символ alpha, а beta вообще нет!
canvas.show()
canvas.write_image("this_image.pdf")
Почему это не работает
Здесь накладывается несколько подводных камней. Исправить какой‑то один — недостаточно; нужны все меры одновременно, чтобы получить корректный перенос.
Первый слой — экранирование в Python. В Plotly нужно передать строку, которая буквально содержит последовательности вида \alpha и \\. В Python '\alpha' — это не то, чем кажется: \a — управляющий символ, поэтому '\alpha' превращается в управляющий сигнал «bell», а затем «lpha». Аналогично, '\\' — это один обратный слеш. Отсюда: запись '\alpha' или '\\' в обычной строке не даст нужного LaTeX. Либо экранируйте каждый слеш в обычной строке — '\\alpha \\\\ \\beta', либо используйте «сырую» строку r'...', чтобы слеши сохранились как есть.
Второй слой — то, как Plotly обрабатывает LaTeX. Как LaTeX разбираются только подписи, которые начинаются и заканчиваются одной парой долларовых знаков. Нельзя разносить формулу по нескольким фрагментам $...$ или смешивать отдельные математические блоки с HTML‑переносами. Попытки вроде "$\alpha$<br>$\beta$" или "$$\alpha$$ <br> $$\beta$$" не дадут желаемого результата.
Третий слой — собственно математический режим LaTeX. Внутри $...$ нельзя произвольно ставить перенос с помощью \\. Переносы допустимы только в определённых окружениях и контекстах. Обычные текстовые конструкции вроде HTML <br> или произвольный \\ не работают как универсальные переносы в math mode. Окружения вроде align поддерживают \\ для разбиения на строки, но переключиться в align внутри единственного встроенного математического контекста, который Plotly ограничивает парой $...$, нельзя.
Рабочее решение
Простой способ расположить символы вертикально, не выходя из математического режима, — воспользоваться матрицей. Мы остаёмся внутри единственной пары $...$, а \\ становится допустимым, потому что используется в окружении, поддерживающем разрывы строк. Главное — передать в Plotly правильную буквальную LaTeX‑строку, чтобы Python по дороге не «съел» обратные слеши.
import plotly.graph_objects as gobj
chart = gobj.Figure()
chart.add_trace(gobj.Box(y=[10, 14]))
chart.update_layout(xaxis_title=r"$\begin{matrix}\alpha\\ \beta\end{matrix}$")
chart.show()
chart.write_image("this_image.pdf")
В заголовке оси α окажется на первой строке, а β — на второй. Такой вариант работает и на экране, и при экспорте через write_image.
Зачем это знать
Подписи в дашбордах и исследовательских графиках часто несут смысловую нагрузку, и корректная вёрстка формул — её часть. Когда сталкиваются экранирование в Python, правила границ LaTeX в Plotly и ограничения математического режима LaTeX, ошибки получаются запутанными. Понимание взаимодействия этих слоёв делает отказы предсказуемыми, а исправление — системным, а не серией угадываний.
Итог
Чтобы надёжно делать перенос строки в подписях Plotly в математическом режиме, передавайте корректно экранированную LaTeX‑строку внутри одной пары долларов и используйте конструкцию, допускающую переносы внутри math mode. Небольшая матрица — простой и эффективный вариант. Следите за литералами строк в Python, не дробите формулу на несколько блоков $ и не смешивайте её с HTML‑переносами, а также выбирайте окружение, где \\ разрешён. Тогда многострочные LaTeX‑подписи будут вести себя одинаково и в интерактивных, и в экспортируемых фигурах.