使用 Plotly 绘制可迭代类

Plot iterable classes with Plotly

提问人:José Fuentes 提问时间:9/9/2023 最后编辑:José Fuentes 更新时间:9/9/2023 访问量:46

问:

我在 Python 中一些可迭代类的情节上遇到了一些问题。这个想法是使用 plotly 绘制从类的迭代器获得的线。下面是该类的示例:

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

只绘制类的一个实例没有问题。例如,以下代码生成正确的线图

import numpy as np
import plotly.express as px

C = example_class(100)
fig = px.line(C)
fig.show()

enter image description here

但是如果我想添加更多行,就像这样

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()

我收到以下错误

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

我尝试了许多替代方案,但没有成功。

有人知道如何解决它吗?

谢谢! 何塞

python plotly 可迭代

评论

0赞 topsail 9/9/2023
由于 C、D 和 E 都是随机数,因此这里没有任何迹象表明 D 和 E 应该或可以共享一个 x 轴。通常,在这种情况下,您可能将 x 轴简单地称为 0-99,并使用该共享的“单位”轴将 D 和 E 绘制在一起。
0赞 José Fuentes 9/9/2023
谢谢,对!我试过了,但我遇到了一个新错误(示例已更新)
0赞 topsail 9/9/2023
看起来做不到。您可能应该将值作为列表传递,而不是这些自定义对象。也许你可以提供一个 PX 可以使用的序列化程序......虽然不确定。
0赞 José Fuentes 9/9/2023
这很糟糕。我的最终目标是表示属性int_part dec_part具有整数序列的紧凑表示形式。因此,我们需要让它与自定义类一起使用。
0赞 José Fuentes 9/9/2023
但是,如果我没记错的话,接下来的方法将演示如何将self.int_part和self.dec_part组合成一个值。所以,对于行应该只是一个值

答:

2赞 RomanPerekhrest 9/9/2023 #1

当构建不同的图形时(特别是 )执行许多不同的检查,其中包括铸造、消毒,如果是生成器/迭代器,则通过构建新索引(或所谓的放置)来实现这些检查 - 在这种情况下,它们之间的大小可能会有所不同。
要处理/自动执行索引准备(对于轴),您可以传递并指定轴所需的 df 列:
lineplotlyxpd.DataFramey

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()

enter image description here

评论

0赞 José Fuentes 9/9/2023
嗨,@RomanPerekhrest,非常感谢。您知道制作 DataFrame 是否会具体化存储在示例类对象中的值,还是只保存对对象的引用?对于上下文,我想提供一种使用紧凑空间绘制时间序列的方法。因此,将存储的值具体化为 list、numpy 数组或与示例类不同的任何其他结构,我将空间增加到 much
1赞 RomanPerekhrest 9/9/2023
@JoséFuentes,无论如何,这些生成器都会实现。在上述解决方案中,数据帧是动态创建的,应被识别为适合进一步检查的数据结构plotly