How to keep Vertical Line Constant irrespective of Zoom in or zoom out in Plotly javascript

Hi Team i want to keep Vertical line constant on zoom out/zoom in currently on zoom out Line changing happening as per the zoom level change.

kindly suggest how to keep line constant without any custom handler
Suggestion will be much appreciable

Hey @nishku, I don’t understand the question.

You might want to be reading into annotations and its coordinate domains.

Hello There,
Here alternate of python plotly, in javascript plotly we are using y0 and y1 for Vertical Line but it’s changing on zoom in and zoom out, i want it to keep constant no matter on zoom in / zoom out
Please note - yref=“paper” is not working for it

I’d expect you want to set xref rather than yref. If you want the line to stay in the same place when you zoom or pan, then does (the js equivalent of) this work? (x specified in pixels, I believe)

fig.add_vline(x=..., xref='paper', ...)

If you want it to move on pan but stay fixed on zoom then I think you’ll probably need to handle the ‘relayout’ event.

1 Like

What exactly is the behaviour you are looking for?

Take this example:

<!DOCTYPE html>
<html>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<body>

<div id="myPlot" style="width:100%;max-width:700px"></div>

<script>
const xArray = [50,60,70,80,90,100,110,120,130,140,150];
const yArray = [7,8,8,9,9,9,10,11,14,14,15];

// Define Data
const data = [{
  x:xArray,
  y:yArray,
  mode:"markers"
}];

// Define Layout
const layout = {
  xaxis: {range: [40, 160], title: "Square Meters"},
  yaxis: {range: [5, 16], title: "Price in Millions"},
  title: "House Prices vs. Size",
  shapes: [{
    type: 'line',
    x0: "70",
    y0: 0,
    x1: "70",
    yref: 'paper',
    y1: 1,
    line: {
      color: 'grey',
      width: 1.5,
      dash: 'dot'
    }
  }]
};

// Display using Plotly
Plotly.newPlot("myPlot", data, layout);
</script>

</body>
</html>

thanks for response @davidharris
but hence i’m using subplot and xref is used here as a reference of other plot, so exactly same fig.add_vline i’m looking in javascript plotly but it’s not due to this i’ve to use relayout and custom handler creating issue for me
Other than - if yref=“paper” using then it’s showing in entire plot not in subplots
so is there any exact same add_vline ?in javascript

Sorry, my mistake. Now I’ve tried it I realise xref=‘paper’ is more limited than I’d thought - it doesn’t seem to work for add_vline() or on subplots.

I have a way of doing this in Python now, hoping it can be transferred to js. The key is to use add_shape() with xref=“x domain” or for subplots other than (1,1), xref=f"x{subplotindex} domain"

Doc at Shapes in Python

e.g.

index = ncols*(row-1) + col  if row > 1 or col > 1 else ""
fig.add_shape(type="line", 
            x0=0.7, y0=0.0, x1=0.7, y1=1.0,
            xref=f"x{index} domain", yref=f"y{index} domain",

This creates this in the figure:

fig.to_dict()["layout"]["shapes"][0]
{'type': 'line', 'x0': 0.7, 'x1': 0.7, 'xref': 'x domain', 'y0': 0.0, 'y1': 1.0, 'yref': 'y domain'}

Here’s a complete working Python code example:

import plotly.graph_objects as go
from plotly.subplots import make_subplots
nrows, ncols = 2,3
fig = make_subplots(rows=nrows, cols=ncols)
for col in range(1, ncols + 1):
    for row in range(1, nrows + 1):
        fig.add_trace(go.Line(x=[0.0, 10.0], y=(2.0, 11.0)), row=row, col=col)
        index = ncols*(row-1) + col  if row > 1 or col > 1 else ""
        fig.add_shape(type="line", 
            x0=0.7, y0=0.0, x1=0.7, y1=1.0,
            xref=f"x{index} domain", yref=f"y{index} domain",
        )
fig.show()

If what you want is this

Animation

This is my configuration

Plotly.update(this.kl.layer, {}, {
    'xaxis.overlaying': `x${this.xaxi}`,
    [`xaxis${this.xaxi}`]: {
        type: 'linear',
        visible: false,
        showgrid: false,
        scaleanchor: 'x1',
        autorange: 'reversed',
        fixedrange: true,
        domain: [0, 1]
    },
    [`shapes[${this.kl.layer.layout.shapes.length}]`]: {
        id: this.id,
        name: this.name,
        type: 'line',
        xref: 'paper',
        yref: 'y',
        x0: 0,
        x1: 1,
        y0: this.poc.price,
        y1: this.poc.price,
        visible: this.poc.show,
        line: {
            color: this.poc.color,
            width: this.poc.width
        }
    },
    [`shapes[${this.kl.layer.layout.shapes.length + 1}]`]: {
        id: this.id,
        name: 'back',
        type: 'rect',
        layer: 'below',
        yref: 'paper',
        xref: 'x',
        x0: this.kl.oTime[this.kl.leftIndex],
        x1: this.kl.oTime[this.kl.rightIndex],
        y0: this.kl.domain[0],
        y1: this.kl.domain[1],
        visible: this.period,
        fillcolor: 'rgba(153,0,255,0.1)',
        line: {
            width: 0
        }
    },
    [`shapes[${this.kl.layer.layout.shapes.length + 2}]`]: {
        id: this.id,
        name: 'left',
        type: 'line',
        layer: 'below',
        yref: 'paper',
        xref: 'x',
        x0: this.kl.oTime[this.kl.leftIndex],
        x1: this.kl.oTime[this.kl.leftIndex],
        y0: this.kl.domain[0],
        y1: this.kl.domain[1],
        visible: this.period,
        opacity: 1,
        line: {
            color: 'rgb(255,255,255)',
            width: 1,
            dash: 'dot'
        }
    },
    [`shapes[${this.kl.layer.layout.shapes.length + 3}]`]: {
        id: this.id,
        name: 'right',
        type: 'line',
        layer: 'below',
        yref: 'paper',
        xref: 'x',
        x0: this.kl.oTime[this.kl.rightIndex],
        x1: this.kl.oTime[this.kl.rightIndex],
        y0: this.kl.domain[0],
        y1: this.kl.domain[1],
        visible: this.period,
        opacity: 1,
        line: {
            color: 'rgb(255,255,255)',
            width: 1,
            dash: 'dot'
        }
    }
})