reflex icon indicating copy to clipboard operation
reflex copied to clipboard

Layout property not pushed through on rx.plotly

Open sebastianjanisch opened this issue 1 year ago β€’ 2 comments

Describe the bug A plotly figure has a data and layout property. It seems that currently only the layout data property is handled.

To Reproduce Steps to reproduce the behavior:

  • Code/Link to Repo:

Rebuilding any example (https://plotly.com/python/line-and-scatter/) that contains layout specifications will not yield the desired result.

Expected behavior A clear and concise description of what you expected to happen.

Layout descriptions in a plotly figure are accounted for when rendering rx.plotly

Screenshots If applicable, add screenshots to help explain your problem.

Specifics (please complete the following information):

  • Python Version: 3.11
  • Reflex Version: 0.4.9
  • OS: Sonoma 14.4.1 (23E224)
  • Browser (Optional): chrome

Additional context Add any other context about the problem here.

sebastianjanisch avatar May 05 '24 19:05 sebastianjanisch

There is a rather ugly hack for the time being. The layout object cannot be serialized right now, but the underlying structure is a plain dict. turning this into a string, then re-evaluating it back to the actual dict and saving it in the state, then passing that through in the plotly component works for now. (I could not find a to_dict or anything. resembling on the plotly layout class).

class MyState(rx.State):
  figure: go.Figure = go.Figure()
  layout: dict[str, Any] = {}

  def on_load(self):
    self.figure = ...
    # some fancy layout properties added to the figure

    self.layout = eval(str(self.figure.layout)[len("Layout(") : -1])


def page() -> rx.Component:
  return rx.plotly(data=MyState.figure, layout=MyState.layout)

sebastianjanisch avatar May 05 '24 21:05 sebastianjanisch

Turns out the figure itself has a to_dict function, so we can use self.layout = self.figure.to_dict()["layout'] as a workaround.

sebastianjanisch avatar May 06 '24 16:05 sebastianjanisch