Search code examples
pythonplotplotlyscatter

Connect gaps between lines with plotly


I have a script that regularly updates a plotly figure and adds a scatter point. I would like a line that connects each point. I obtain the equivalent of this code:

import plotly.graph_objects as go

fig = go.Figure()

fig.add_scatter(x=[1],y=[2])
fig.add_scatter(x=[5],y=[4])

noline

while I would like the output of this code (so with a line connecting the points)

import plotly.graph_objects as go

fig = go.Figure()

fig.add_scatter(x=[1,5],y=[2,4])

line

Unfortunately I can't join [1] and [5] because I am taking the data from a file that is updated regularly.


Solution

  • You're trying to add a line between markers from two different traces since you're using:

    fig.add_scatter(x=[1],y=[2])
    fig.add_scatter(x=[5],y=[4])
    

    And to my knowledge, that just won't work. Lines can only be drawn between the same points in the same trace. I'm not sure I understand why you can't store new values in a lists, but we'll leave that out of the discussion for now. The god news is that you can access the data for your x and y values in your fig objects through:

    fig.data[0].x
    fig.data[0].y
    

    And you can append further vales to them as well. Alas not directly, since they are tuples. So you'll have to switch between lists and tuples, but that's not a very big problem.

    First, set up your 'base' case like this:

    import plotly.graph_objects as go
    fig = go.Figure()
    fig.add_scatter(x=[1],y=[2])
    fig.show()
    

    enter image description here

    Then, build on the existing values in the fig` object with new values:

    fig.data[0].x = tuple(list(fig.data[0].x) + [4])
    fig.data[0].y = tuple(list(fig.data[0].y) + [5])
    fig.show()
    

    enter image description here

    And as you can see, a line is automatically added between those points because they are points in the same trace.

    Random numbers

    Here's another snippet that adds random values to an existing trace in a figure:

    fig.data[0].x = tuple(list(fig.data[0].x) + np.random.randint(low=0, high=10, size=1).tolist())
    fig.data[0].y = tuple(list(fig.data[0].y) + np.random.randint(low=0, high=10, size=1).tolist())
    fig.show()
    

    If you run that a few times, for example in its own JupyterLab cell, you'll end up with something like this:

    enter image description here

    Random walk

    And here's another example that takes the last value in your trace, and adds a random number, so you'll end up with a series in the plot below:

    fig.data[0].x = tuple(list(fig.data[0].x) + [(list(fig.data[0].x)[-1] + 1)])
    fig.data[0].y = tuple(list(fig.data[0].y) + (list(fig.data[0].y)[-1] + np.random.randint(low=-1, high=2, size=1)).tolist())
    fig.show()
    

    enter image description here

    And notice that the x-values in this case has been set up to increase by 1 for each run as opposed to the example above.