Установка диапазона осей для подграфиков в Plotly-Python

Вопрос или проблема

Я пытаюсь вручную установить диапазон одной (общей) оси y в многопанельном графике Plotly, но по какой-то причине это также влияет на диапазон других осей y.
Посмотрите на этот пример. Я начну с создания фигуры 3×2, с общей осью y для каждой строки.

import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.io as pio

pio.renderers.default = "browser"

np.random.seed(42)

N = 20
nrows, ncols, ntraces = 3, 2, 3

fig = make_subplots(
    rows=nrows, cols=ncols,
    shared_xaxes=True, shared_yaxes=True,
)

for r in range(nrows):
    scale = 1 / 10 ** r
    for c in range(ncols):
        for t in range(ntraces):
            y = np.random.randn(N) * scale
            fig.add_trace(
                row=r + 1, col=c + 1,
                trace=go.Scatter(y=y, mode="markers+lines", name=f"trace {t}")
            )
fig.update_layout(showlegend=False)
fig.show()

Это генерирует следующую фигуру:
график для многопанельной фигуры

Теперь я хочу вручную установить диапазон только для первой строки, поэтому я делаю:

fig.update_yaxes(range=[-2, 2], row=1, col=1)
fig.show()

Это действительно устанавливает диапазон как требуется. Проблема в том, что это также нарушает все другие оси, меняя их диапазон на какое-то автоматическое значение ([-1, 4]):
Неверный диапазон

Я пробовал вручную установить диапазон других строк, используя различные комбинации range и rangemode="normal", например:

fig.update_yaxes(range=[None, None], row=2, col=1)
fig.update_yaxes(range=None, row=2, col=1)
fig.update_yaxes(rangemode="normal", row=2, col=1)

Ничто не работает…
Как я могу вручную установить диапазон оси y только для одной из осей?

Похоже, это ошибка, вероятно, вызванная тем, что установлены оба параметра shared_xaxes=True и shared_yaxes=True.

Я не думаю, что вы можете обновить только одну ось y (поскольку они общие), но вы все еще можете обновить пары осей y (в одной строке) и установить autorange=True, чтобы предотвратить такое странное поведение для тех осей, диапазон которых не должен обновляться:

fig.update_yaxes(range=[-2, 2], row=1)  # 'y'  и 'y2'
fig.update_yaxes(autorange=True, row=2) # 'y3' и 'y4'
fig.update_yaxes(autorange=True, row=3) # 'y5' и 'y6'

Вы также можете сделать это за один вызов, указав идентификаторы осей любой пары:

fig.update_layout(
    yaxis_range=[-2, 2],    # 'y'  и 'y2'
    yaxis3_autorange=True,  # 'y3' и 'y4'
    yaxis5_autorange=True,  # 'y5' и 'y6'
)

Ответ или решение

Ваша проблема связана с тем, что при использовании параметров shared_yaxes=True и shared_xaxes=True оси Y на одной и той же строке делят одни и те же настройки диапазона. Это может привести к тому, что изменение диапазона для одной оси Y также изменяет диапазоны для других осей Y, которые связаны с ней.

Чтобы установить диапазон только для одной строки графиков, вам необходимо использовать параметр autorange=True для других рядов. Это позволит сохранить автоматически вычисляемый диапазон для этих осей, избегая нежелательных изменений.

Вот как можно это сделать:

import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.io as pio

pio.renderers.default = "browser"

np.random.seed(42)

N = 20
nrows, ncols, ntraces = 3, 2, 3

fig = make_subplots(
    rows=nrows, cols=ncols,
    shared_xaxes=True, shared_yaxes=True,
)

for r in range(nrows):
    scale = 1 / 10 ** r
    for c in range(ncols):
        for t in range(ntraces):
            y = np.random.randn(N) * scale
            fig.add_trace(
                row=r + 1, col=c + 1,
                trace=go.Scatter(y=y, mode="markers+lines", name=f"trace {t}")
            )
fig.update_layout(showlegend=False)

# Устанавливаем диапазон для первой строки
fig.update_yaxes(range=[-2, 2], row=1)  # Установка диапазона для значений y для 'y' и 'y2'
# Для остальных строк устанавливаем авто диапазон, чтобы избежать изменений
fig.update_yaxes(autorange=True, row=2)  # 'y3' и 'y4'
fig.update_yaxes(autorange=True, row=3)  # 'y5' и 'y6'

fig.show()

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

Еще один способ сделать это – использовать метод update_layout(), чтобы одновременно установить диапазоны для различных осей:

fig.update_layout(
    yaxis_range=[-2, 2],    # 'y'  и 'y2'
    yaxis3_autorange=True,  # 'y3' и 'y4'
    yaxis5_autorange=True,  # 'y5' и 'y6'
)

Эти методы позволяют вам контролировать диапазон осей в многопанельных графиках и избегать нежелательных эффектов, связанных с совместным использованием осями. Надеюсь, это поможет решить вашу проблему!

Оцените материал
Добавить комментарий

Капча загружается...