Skip to content

add_hline not working for make_subplots if not populated #5136

Description

@NoniosTheMad

Whenever you add a hline/vline to a plot it should display it at the given position. However, when the figure is made with make_subplots and is not yet populated with data, it never shows the line.

import plotly.graph_objects as go
from plotly.subplots import make_subplots

for name, fig in {
    "go.Figure": go.Figure(),
    "make_subplots": make_subplots(rows=1, cols=1)
}.items():
    fig.add_hline(y=0.5)
    # Add a trace after the line
    fig.add_trace(go.Scatter(x=[1, 2], y=[0, 1]))
    fig.update_layout(title=name)
    fig.show()

Image
Image

pip list

Package Version


asttokens 3.0.0
attrs 25.3.0
colorama 0.4.6
comm 0.2.2
debugpy 1.8.13
decorator 5.2.1
executing 2.2.0
fastjsonschema 2.21.1
ipykernel 6.29.5
ipython 9.0.2
ipython_pygments_lexers 1.1.1
jedi 0.19.2
jsonschema 4.23.0
jsonschema-specifications 2024.10.1
jupyter_client 8.6.3
jupyter_core 5.7.2
matplotlib-inline 0.1.7
narwhals 1.31.0
nbformat 5.10.4
nest-asyncio 1.6.0
packaging 24.2
parso 0.8.4
pip 24.3.1
platformdirs 4.3.7
plotly 6.0.1
prompt_toolkit 3.0.50
psutil 7.0.0
pure_eval 0.2.3
Pygments 2.19.1
python-dateutil 2.9.0.post0
pywin32 310
pyzmq 26.3.0
referencing 0.36.2
rpds-py 0.23.1
six 1.17.0
stack-data 0.6.3
tornado 6.4.2
traitlets 5.14.3
typing_extensions 4.12.2
wcwidth 0.2.13

Activity

  1. added
    bugsomething broken
    P2considered for next cycle
    on Apr 9, 2025
  2. gvwilson commented on Apr 9, 2025

    @gvwilson
    Contributor

    thanks for the bug report @NoniosTheMad

  3. self-assigned this
    on Jul 3, 2025
  4. removed their assignment
    on Aug 9, 2025
  5. leavor commented on Nov 14, 2025

    @leavor

    plotly.py verson 6.4.0, has same issue

  6. ioseba commented on Oct 13, 2026

    @ioseba

    Hi @NoniosTheMad @gvwilson, I investigated the root cause of this behavior in plotly.py.

    Root Cause

    In Figure.add_hline() and �dd_vline(), �xclude_empty_subplots defaults to True.

    When a figure is initialized via make_subplots(), _has_subplots() is True. During _add_annotation_like() in plotly/basedatatypes.py:
    python if exclude_empty_subplots and ( not self._subplot_not_empty( xref, yref, selector=bool(exclude_empty_subplots) ) ): return self
    Since self.data is empty at that point, _subplot_not_empty() evaluates to False for all subplots. The shape is silently dropped (
    eturn self) instead of being appended to layout.shapes. When ig.add_trace(...) is called afterwards, the shape is already lost.

    In contrast, on a bare go.Figure(), _has_subplots() is False, which resets
    ow and col to None. This bypasses the subplot grid check entirely and allows �dd_hline() to succeed before data is added.

    Proposed Fix

    We can adjust the check in _add_annotation_like() so that �xclude_empty_subplots only filters subplots when the figure actually contains plotted data (i.e. �ool(self.data)), preserving reference lines configured prior to populating traces.

    Happy to open a PR with regression unit tests covering �dd_hline/�dd_vline on unpopulated subplots if this direction sounds good to the maintainers!

  7. camdecoster commented on Oct 15, 2026

    @camdecoster
    Contributor

    I think a better idea would be to skip exclude_empty_subplots when it's obvious that the user wants the line such as:

    • Only one subplot exists
    • The user passes in a specific subplot via row/col
  8. ioseba commented on Oct 18, 2026

    @ioseba

    Thanks for sharing your perspective @camdecoster! That is a really interesting point — when specific
    ow and col arguments are passed, the intent to target that exact cell is very clear.

    At the same time, we completely understand the maintainers' rationale discussed earlier in #5254 regarding how �xclude_empty_subplots was designed to avoid cluttering empty grids. The tricky part from a user standpoint is just the subtle order-of-operations effect: calling �dd_hline() before versus after �dd_trace() behaves differently because the shape gets dropped if traces aren't present yet.

    @emilykl @gvwilson Whenever you have a chance to take a look, we would love to hear your thoughts on what you feel is the best direction for plotly.py:

    1. Keeping the current behavior as-is and recommending �xclude_empty_subplots=False (perhaps adding a small note in the docstring to help users who run into this).
    2. Or allowing a small tweak so that explicit
      ow/col targets aren't dropped before data is populated.

    No rush at all, and happy to help with either a docs clarification or a small PR depending on what the team prefers!

  9. camdecoster commented on Oct 19, 2026

    @camdecoster
    Contributor

    I think it's okay to make the small changes that I described to make the library more user friendly. If you want to do that, we can review a PR. FYI, those users that you tagged aren't maintainers here (while I am), so they wouldn't be able to make a decision on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2considered for next cyclebugsomething brokensize: 1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions