python - plotly .ly : Different height for subplots with shared X-Axes

标签 python plotly plotly-dash

背景

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

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

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')

enter image description here

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

我还可以使用具有共享 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')

enter image description here

问题

How to to create subplots with shared x-axes where you have both a title (fig 1) and different relative height (fig 2) for each subplot?


我尝试过的

  • 使用 subplotsrowspan

第一个 hack 是创建一个额外的行,使 plot 跨越其中的两个:

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)

enter image description here

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

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

  • 使用

一个稍微好一点的选择是使用带有 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)

enter image description here

最佳答案

此错误已由 Kully 在 PR #1245 中解决并且已在 dash v3.4.0 中修复。

enter image description here

以下代码 — 仅使用 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)

关于python - plotly .ly : Different height for subplots with shared X-Axes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52856836/

相关文章:

python - Flask 无法识别我的自定义样式表

python - plotly:如何向现有图形添加文本?

Python plotly : Adding a horizontal line to a scatter plot that has multiple subplots

python - 在多选项卡破折号应用程序中将回调分配给组件的问题

python - 从 SQL 查询生成绘图数据表

python - Pandas DateTime 索引重采样不起作用

python - 如何确定二维列表是否包含值?

python - 将 pandas 系列的 collections.counter 对象转换为 pandas dataframe 的多列

python - 精神科PG2 : Querying using an external Variable In a Dash App

R仅将颜色填充到下一个y的上值