Updating plotly pane

I have a Plotly pane pn.pane.Plotly in which I have a plotly.go.Figure(). I update the plot on a button press, by calling a function which creates a entirely new go.Figure() and then replaces the figure that is used by the Plotly pane, as follows:

class PlotlyPlot:
    def __init__(self):
        self.figure= go.Figure()
        self.plotlyplane = pn.pane.Plotly(self.figure)
        self.update = pn.widgets.Button(name='Update')
        self.update.on_click(self.update_plot)
   def update_plot(self):
        # Get data here
        new_fig = go.Figure()
        new_fig.add_trace(**data) # 2-3 add traces
        new_fig.update_layout(**properties)
        self.figure = new_fig
        self.plotlyplane.object = self.figure

Now this was working completely fine, but I added a new add_trace statement, which essentially is a dummy trace (no actual data). I use the following code for it.
new_fig.add_trace(go.Scatter(x=[0], y=[0], name='Name', legendgroup='Group Name')

Now when I update my plot, there are some remnants in my Plotly panel. The newly added dummy trace seems to be mirroring some other data that I have plotted. I tried printing out self.figure['data'] and everything is as it’s supposed to be, but the plot is inconsistent. I am not sure why. And the plot was working perfectly fine till the addition of the new dummy scatter. Any help would be appreciated.

I found the following in the documentation regarding plotly.

Once created the plot can be updated by modifying the Plotly traces and then triggering an update by setting or triggering an event on the pane object. Note that this only works if the Figure is defined as a dictionary, since Plotly will make copies of the traces, which means that modifying them in place has no effect. Modifying an array will send just the array using a binary protocol, leading to fast and efficient updates.

However I was not sure what exactly it means, if someone could clarify that’d be great.

I figured out the issue. It was that I was using lists for my x and y values for the dummy trace I was adding. By converting them to an np.array the problem was solved.

new_fig.add_trace(go.Scatter(x=np.array([0]), y=np.array([0]), name='Name', legendgroup='Group Name')
Making the above change made the trace behave properly. Earlier it was taking on values from a previously plotted trace. Not sure why exactly.

I can create a functional minimal repeatable example if someone wants to dig in more detail.

1 Like