【问题标题】:Plot.ly: Different height for subplots with shared X-AxesPlot.ly:具有共享 X 轴的子图的不同高度
【发布时间】:2019-03-22 05:57:51
【问题描述】:

背景

  • 具有相同高度的不同子图 (✔) (✘)

我可以使用 共享 X 轴的子图 创建一个图表(示例改编自 Plot.ly doc),子图之间有适当的分隔,并且您可以通过 @987654333 为每个子图插入特定标题@:

from plotly import tools
import plotly.plotly as py
import plotly.graph_objs as go

trace1 = go.Scatter(
    x=[0, 1, 2],
    y=[10, 11, 12]
)
trace2 = go.Scatter(
    x=[2, 3, 4],
    y=[100, 110, 120],
)
trace3 = go.Scatter(
    x=[3, 4, 5],
    y=[1000, 1100, 1200],
)
fig = tools.make_subplots(rows=3, cols=1, specs=[[{}], [{}], [{}]],
                          shared_xaxes=True, shared_yaxes=True,
                          vertical_spacing=0.1, subplot_titles=('subtitle 1', 
                          'subtitle 2', 'subtitle 3'))
fig.append_trace(trace1, 3, 1)
fig.append_trace(trace2, 2, 1)
fig.append_trace(trace3, 1, 1)

fig['layout'].update(height=600, width=600, title='Subplots with Shared X-Axes')
py.plot(fig, filename='subplots-shared-xaxes')

  • 合并的子图 (✘) 具有不同的高度 (✔)

我还可以使用带有共享 X 轴的堆叠子图创建一个图形(示例改编自 Plot.ly doc),您可以在其中通过 domain 定义每个子图的相对高度:

from plotly import tools
import plotly.plotly as py
import plotly.graph_objs as go

trace1 = go.Scatter(
    x=[0, 1, 2],
    y=[10, 11, 12]
)
trace2 = go.Scatter(
    x=[2, 3, 4],
    y=[100, 110, 120],
    yaxis='y2'
)
trace3 = go.Scatter(
    x=[3, 4, 5],
    y=[1000, 1100, 1200],
    yaxis='y3'
)
data = [trace1, trace2, trace3]
layout = go.Layout(
    yaxis=dict(
        domain=[0, 0.25]
    ),
    legend=dict(
        traceorder='reversed'
    ),
    yaxis2=dict(
        domain=[0.25, 0.75]
    ),
    yaxis3=dict(
        domain=[0.75, 1]
    )
)
fig = go.Figure(data=data, layout=layout)
fig['layout'].update(height=600, width=600, title='Stacked Subplots with Shared X-Axes')
py.plot(fig, filename='stacked-subplots-shared-x-axis')

问题

如何创建 具有共享 x 轴的子图,其中您有标题(图 1)和不同的相对高度(图2) 对于每个子图


我的尝试

  • 使用subplotsrowspan

第一个技巧是创建一个额外的行,使绘图跨越其中两个:

from plotly import tools
import plotly.plotly as py
import plotly.graph_objs as go

trace1 = go.Scatter(
    x=[0, 1, 2],
    y=[10, 11, 12]
)
trace2 = go.Scatter(
    x=[2, 3, 4],
    y=[100, 110, 120],
)
trace3 = go.Scatter(
    x=[3, 4, 5],
    y=[1000, 1100, 1200],
)
fig = tools.make_subplots(
    rows=4,
    cols=1,
    specs=[
        [{}],
        [{'rowspan':2}],
        [None],
        [{}],
    ],
    shared_xaxes=True,
    shared_yaxes=True,
    vertical_spacing=0.1,
    subplot_titles=(
        'subtitle 1',
        'subtitle 2',
        None,
        'subtitle 3',
    )
)
fig.append_trace(trace3, 1, 1)
fig.append_trace(trace2, 2, 1)
fig.append_trace(trace1, 4, 1)

fig['layout'].update(height=600, width=600, title='Subplots with Shared X-Axes, span rows')
py.plot(fig, filename='subplots-shared-x-axis-span-rows', auto_open=True)

结果正是我想要实现的。但是,这个 hack 对我来说似乎错误:从语法上讲,我不想要一个跨越两个行。此外,如果要修改任何内容,必须将 [None] 添加到 specsNonesubplot_titles 是丑陋且容易出错的。

还要考虑您想要子图的13% | 70% | 17% 高度分布的情况!

  • 使用domain

一个更好的选择是使用带有domain 的更新轴,但是子图标题会变得混乱(它们仍然垂直均匀分布):

from plotly import tools
import plotly.plotly as py
import plotly.graph_objs as go

trace1 = go.Scatter(
    x=[0, 1, 2],
    y=[10, 11, 12]
)
trace2 = go.Scatter(
    x=[2, 3, 4],
    y=[100, 110, 120],
)
trace3 = go.Scatter(
    x=[3, 4, 5],
    y=[1000, 1100, 1200],
)
fig = tools.make_subplots(
    rows=3,
    cols=1,
    specs=[[{}], [{}], [{}]],
    shared_xaxes=True,
    shared_yaxes=True,
    vertical_spacing=0.1,
    subplot_titles=(
        'subtitle 1',
        'subtitle 2',
        'subtitle 3'
    )
)
fig.append_trace(trace1, 3, 1)
fig.append_trace(trace2, 2, 1)
fig.append_trace(trace3, 1, 1)

fig['layout'].update(height=600, width=600, title='Subplots with Shared X-Axes and `domain` hack')
fig['layout']['yaxis1'].update(domain=[0, 0.2])
fig['layout']['yaxis2'].update(domain=[0.3, 0.7])
fig['layout']['yaxis3'].update(domain=[0.8, 1])
py.plot(fig, filename='subplots-shared-x-axis-domain-hack', auto_open=True)

【问题讨论】:

标签: python plotly plotly-dash


【解决方案1】:

Kully 在PR #1245 中解决了这个错误,并在dash v3.4.0修复了

以下代码 - 仅使用 3 个子图和 row_width=[0.2, 0.4, 0.2] - 因此应该可以完美运行:

from plotly import tools
import plotly.plotly as py
import plotly.graph_objs as go

trace1 = go.Scatter(
    x=[0, 1, 2],
    y=[10, 11, 12]
)
trace2 = go.Scatter(
    x=[2, 3, 4],
    y=[100, 110, 120],
)
trace3 = go.Scatter(
    x=[3, 4, 5],
    y=[1000, 1100, 1200],
)
fig = tools.make_subplots(rows=3, cols=1,
                          shared_xaxes=True,
                          vertical_spacing=0.1,
                          subplot_titles=('subtitle 1', 'subtitle 2', 'subtitle 3'),
                          row_width=[0.2, 0.4, 0.2]
                         )

fig.append_trace(trace1, 3, 1)
fig.append_trace(trace2, 2, 1)
fig.append_trace(trace3, 1, 1)

fig['layout'].update(height=600, width=600, title='Subplots with Shared X-Axes')
go.FigureWidget(fig)

【讨论】:

  • 你能在绘制后更新行高吗?在我的情况下,迭代一个列表,创建跟踪..当我将跟踪添加到一行时,我想在那个时候设置行高
猜你喜欢
  • 2018-01-04
  • 2013-01-22
  • 1970-01-01
  • 2020-03-06
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 2017-12-07
  • 2020-06-11
相关资源
最近更新 更多