Вопрос или проблема
Я пытаюсь вручную установить диапазон одной (общей) оси 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'
)
Эти методы позволяют вам контролировать диапазон осей в многопанельных графиках и избегать нежелательных эффектов, связанных с совместным использованием осями. Надеюсь, это поможет решить вашу проблему!