✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚾️ It's finally Baseball season! Root for the home team... & Register for our Sports Analytics Webinar!

Annotation, Ticks, and Range chart cutoff

The code below produces the chart that precedes it. Here are several questions about it:

  1. The yaxis range is [0,5] and the xaxis range is [0,2]. This cuts off half the line from (0,0) to (0,3) and three-quarters of the marker at (2,5). Removing the range results in too much padding in the chart. Is there a way to control the amount of padding in the chart area?
  2. yaxis2 has the tick labels “Three”, “Four”, and “Five”, however “Five” is not shown. It’s not even cutoff, it’s just not shown even though ticklabelposition = "inside". Why is this? How can I use both the range option and show a tick label on the inside of a chart?
  3. The annotations “Zero”, “One”, and “Two” are shown above the trace layer. Is there a way to move them below the trace layer but above the shape layer? If not, is there a way to provide a background color for tick labels? My goal is to hide the portion of the gray line shape that is behind the annotation/tick label.
  4. Despite having yref='y',yanchor='middle', the annotations “Zero”, “One”, and “Two” are slightly lower than the 0, 1, and 2 ticks on the y axis. Why is this? Shouldn’t they align perfectly with these ticks given these options?

import datetime
import plotly.graph_objects as go

xvals=[0,0,0,0,1,2]
yvals=[0,1,2,3,4,5]

fig = go.Figure()

fig.add_trace(
    go.Scatter(
        x=xvals,
        y=yvals,
        line_width=4,
        marker_size=10,
        showlegend=False,
    ),
)

fig.add_trace(
    go.Scatter(
        x=xvals,
        y=yvals,
        mode="none",
        yaxis="y2",
        hoverinfo="skip",
        showlegend = False,
    )
)

fig.update_layout(
    go.Layout(
        paper_bgcolor='rgba(0,0,0,0)',
        plot_bgcolor='rgba(0,0,0,0)',
        yaxis=dict(
            ticks="outside",
            tickcolor='white',
            ticklen=7,
            tickmode='array',
            tickvals=yvals,
            range=[min(yvals),max(yvals)],
            showgrid=False,
        ),
        yaxis2=dict(
            ticks="outside",
            ticklen=7,
            tickmode = 'array',
            tickvals = [3,4,5],
            ticktext = ["Three","Four","Five"],
            range=[min(yvals),max(yvals)],
            layer="below traces",
            ticklabelposition ="inside",
            anchor="x",
            overlaying="y",
            side="left",
            showgrid=False,
        ),
        xaxis=dict(
            tickmode="linear",
            ticklen=7,
            showgrid=False,
            range=[min(xvals),max(xvals)],
        ),
    ),
)

# add lines
color = "black"
for y in yvals:
    fig.add_shape(
        type="line",
        xref="paper",
        x0=0,
        y0=y,
        x1=1,
        y1=y,
        layer="below",
        line=dict(
            color=color,
            width=0.5,
            dash="solid",
        )
    )

# add annotations
annotations=[]
for y,text in zip([0,1,2],["Zero","One","Two"]):
    annotations.append(
        dict(
            xref='paper',
            yref='y',
            x=0,
            y=y,
            xanchor='left',
            yanchor='middle',
            text=text,
            bgcolor='white',
            showarrow=False,
        ),
    )
fig.update_layout(annotations=annotations)

fig.show()