I'm having some problems with the plot of some iterable classes in Python. The idea is to use plotly to plot lines obtained from the iterator of a class. Here is an example of the class:
class example_class:
## Constructor
def __init__(self, n):
self.int_part = np.random.randint(0, 1023, size=n, dtype=np.uint16)
self.dec_part = np.random.randint(0, 127, size=n, dtype=np.uint16)
self.current = 0
self.n = n
## Iterator
def __iter__(self):
return self
## Next element during the iteration
def __next__(self):
if self.current < self.n:
v = self.int_part[self.current] + self.dec_part[self.current]/100
self.current += 1
return v
raise StopIteration
## Length
def __len__(self):
return self.n
There is not problem to plot just one instance of the class. For example, the following code generate a correct line plot
import numpy as np
import plotly.express as px
C = example_class(100)
fig = px.line(C)
fig.show()
But if I want to add more lines, like this
import numpy as np
import plotly.express as px
C = example_class(100)
D = example_class(100)
E = example_class(100)
fig = px.line(x=np.arange(0,100), y=[D,E])
fig.show()
I get the following error
Traceback (most recent call last):
File "test.py", line 34, in <module>
fig.show()
File "/home/jose/anaconda3/lib/python3.7/site-packages/plotly/basedatatypes.py", line 3409, in show
return pio.show(self, *args, **kwargs)
File "/home/jose/anaconda3/lib/python3.7/site-packages/plotly/io/_renderers.py", line 403, in show
renderers._perform_external_rendering(fig_dict, renderers_string=renderer, **kwargs)
File "/home/jose/anaconda3/lib/python3.7/site-packages/plotly/io/_renderers.py", line 340, in _perform_external_rendering
renderer.render(fig_dict)
File "/home/jose/anaconda3/lib/python3.7/site-packages/plotly/io/_base_renderers.py", line 759, in render
validate=False,
File "/home/jose/anaconda3/lib/python3.7/site-packages/plotly/io/_html.py", line 144, in to_html
jdata = to_json_plotly(fig_dict.get("data", []))
File "/home/jose/anaconda3/lib/python3.7/site-packages/plotly/io/_json.py", line 143, in to_json_plotly
json.dumps(plotly_object, cls=PlotlyJSONEncoder, **opts), _swap_json
File "/home/jose/anaconda3/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/home/jose/anaconda3/lib/python3.7/site-packages/_plotly_utils/utils.py", line 59, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File "/home/jose/anaconda3/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/home/jose/anaconda3/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/jose/anaconda3/lib/python3.7/site-packages/_plotly_utils/utils.py", line 136, in default
return _json.JSONEncoder.default(self, obj)
File "/home/jose/anaconda3/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type example_class is not JSON serializable
I tried many alternatives without success.
Anyone has an idea how to solve it?
Thanks! José
When building different figures (in particular line
) plotly
performs a lot of different checks which, among of others, include casting, sanitizing and, in case of generators/iterators, materializing those with constructing a new index (or so-called placement) - the sizes between them may diverge in such cases.
To handle/automate index preparation (for x
axis) you can pass pd.DataFrame
and specify the needed df columns for y
axis:
import numpy as np
import pandas as pd
import plotly.express as px
fig = px.line(pd.DataFrame({'D': example_class(100),
'E': example_class(100)}), y=['D', 'E'])
fig.show()