holoviz / holoviews

With Holoviews, your data visualizes itself.
https://holoviews.org
BSD 3-Clause "New" or "Revised" License
2.66k stars 396 forks source link

Pickling object does not preserve `opts` #6286

Open ahuang11 opened 2 weeks ago

ahuang11 commented 2 weeks ago
import pickle
import holoviews as hv
hv.extension("bokeh")

curve = hv.Curve([0, 1, 2], kdims=["XAXIS"]).opts(color="red")
pickle.loads(pickle.dumps(curve))

Expected:

image

Actual:

image
ahuang11 commented 2 weeks ago

There's some differences in operations: __getstate__ obj_dict

{
    '_in_method': False,
    'interface': <class 'holoviews.core.data.dictionary.DictInterface'>,
    'data': OrderedDict([
        ('XAXIS', array([0, 1, 2])),
        ('y', array([0, 1, 2]))
    ]),
    '_id': None,
    '_plot_id': 4362542608,
    '_param__private': <param.parameterized._InstancePrivate object at 0x1342eaec0>,
    'ndims': 1,
    '_cached_constants': {},
    '_settings': None,
    '_pipeline': chain(
        dynamic='default', 
        group='', 
        input_ranges={}, 
        link_inputs=False, 
        name='chain00873', 
        operations=[
            factory(
                args=[], 
                dynamic='default', 
                group='Operation', 
                input_ranges={}, 
                kwargs={'kdims': [Dimension('XAXIS')], 'vdims': [Dimension('y')]}, 
                link_inputs=False, 
                name='factory00860', 
                output_type=<class 'holoviews.element.chart.Curve'>, 
                streams=[]
            ), 
            factory(
                args=[], 
                dynamic='default', 
                group='Operation', 
                input_ranges={}, 
                kwargs={'mode': None}, 
                link_inputs=False, 
                name='factory00871', 
                output_type=<class 'holoviews.core.accessors.Opts'>, 
                streams=[]
            ), 
            method(
                args=[], 
                dynamic='default', 
                group='Operation', 
                input_ranges={}, 
                input_type=<class 'holoviews.core.accessors.Opts'>, 
                kwargs={'color': 'red'}, 
                link_inputs=False, 
                method_name='call', 
                name='method00872', 
                output_type=None, 
                streams=[]
            )
        ], 
        output_type=<class 'holoviews.element.chart.Curve'>, 
        streams=[]
    ),
    '_transforms': [],
    '_cached': None,
    '_dataset': None,
    '_index_skip': False
}

__setstate__ d

{
    '_in_method': False,
    'interface': <class 'holoviews.core.data.dictionary.DictInterface'>,
    'data': OrderedDict([
        ('XAXIS', array([0, 1, 2])),
        ('y', array([0, 1, 2]))
    ]),
    '_id': None,
    '_plot_id': 4426047952,
    '_param__private': <param.parameterized._InstancePrivate object at 0x13d5f34c0>,
    'ndims': 1,
    '_cached_constants': {},
    '_settings': None,
    '_pipeline': chain(
        dynamic='default',
        group='',
        input_ranges={},
        link_inputs=False,
        name='chain00874',
        operations=[
            factory(
                args=[],
                dynamic='default',
                group='Operation',
                input_ranges={},
                kwargs={'kdims': [Dimension('XAXIS')], 'vdims': [Dimension('y')]},
                link_inputs=False,
                name='factory00860',
                output_type=<class 'holoviews.element.chart.Curve'>,
                streams=[]
            )
        ],
        output_type=<class 'holoviews.element.chart.Curve'>,
        streams=[]
    ),
    '_transforms': [],
    '_cached': None,
    '_dataset': None,
    '_index_skip': False
}

From ChatGPT:

Plot ID:

First dictionary: _plot_id: 4362542608 Second dictionary: _plot_id: 4426047952 Pipeline Name:

First dictionary: name='chain00873' Second dictionary: name='chain00874' Operations within Pipeline:

First dictionary has three operations (one factory with kwargs={'kdims': [Dimension('XAXIS')], 'vdims': [Dimension('y')]}, another factory with kwargs={'mode': None}, and a method with kwargs={'color': 'red'}). Second dictionary has only one operation (a factory with kwargs={'kdims': [Dimension('XAXIS')], 'vdims': [Dimension('y')]}). _param__private Memory Address:

First dictionary: _paramprivate: <param.parameterized._InstancePrivate object at 0x1342eaec0> Second dictionary: _paramprivate: <param.parameterized._InstancePrivate object at 0x13d5f34c0>