hgrecco / pint-pandas

Pandas support for pint
Other
173 stars 42 forks source link

Feature request: support plotly backend for pandas plotting #249

Open hdavid16 opened 3 months ago

hdavid16 commented 3 months ago

This package is amazing. I have been struggling to use the plotly backend for pandas plots when my dataframe has units associated with it. I have had to strip out the units to get the plotting to work. Is there a way to plot a pint_dataframe with plotly?

I'm happy to provide a MWE if that helps.

Thanks.

andrewgsavage commented 3 months ago

what errors do you get?

hdavid16 commented 3 months ago

MWE:

import pandas as pd
import pint_pandas as ppi
import matplotlib.pyplot as plt
pd.options.plotting.backend = "plotly"
ppi.PintType.ureg.setup_matplotlib()

df = pd.DataFrame({'A': pd.Series([1,2,3], dtype="pint[m]")})
df['A'].plot()

AttributeError: 'int' object has no attribute 'tolist'

This works:

df['A'].pint.magnitude.plot()

Package versions (on Python 3.10):

        'pandas>=2.2.2',
        'numpy>=2.0.1',
        'Pint>=0.24.3',
        'Pint-Pandas>=0.6.2',
        'matplotlib>=3.9.2',
        'plotly>=5.23.0',
        'nbformat>=4.2.0'
andrewgsavage commented 3 months ago
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) File ~\mambaforge\envs\pp_aug241\Lib\site-packages\pint\facets\plain\quantity.py:1424, in PlainQuantity.tolist(self) 1423 try: -> 1424 values = self._magnitude.tolist() 1425 if not isinstance(values, list): AttributeError: 'float' object has no attribute 'tolist' During handling of the above exception, another exception occurred: AttributeError Traceback (most recent call last) File ~\mambaforge\envs\pp_aug241\Lib\site-packages\IPython\core\formatters.py:925, in IPythonDisplayFormatter.__call__(self, obj) 923 method = get_real_method(obj, self.print_method) 924 if method is not None: --> 925 method() 926 return True File ~\mambaforge\envs\pp_aug241\Lib\site-packages\plotly\basedatatypes.py:832, in BaseFigure._ipython_display_(self) 829 import plotly.io as pio 831 if pio.renderers.render_on_display and pio.renderers.default: --> 832 pio.show(self) 833 else: 834 print(repr(self)) File ~\mambaforge\envs\pp_aug241\Lib\site-packages\plotly\io\_renderers.py:386, in show(fig, renderer, validate, **kwargs) 383 fig_dict = validate_coerce_fig_to_dict(fig, validate) 385 # Mimetype renderers --> 386 bundle = renderers._build_mime_bundle(fig_dict, renderers_string=renderer, **kwargs) 387 if bundle: 388 if not ipython_display: File ~\mambaforge\envs\pp_aug241\Lib\site-packages\plotly\io\_renderers.py:294, in RenderersConfig._build_mime_bundle(self, fig_dict, renderers_string, **kwargs) 291 if hasattr(renderer, k): 292 setattr(renderer, k, v) --> 294 bundle.update(renderer.to_mimebundle(fig_dict)) 296 return bundle File ~\mambaforge\envs\pp_aug241\Lib\site-packages\plotly\io\_base_renderers.py:578, in IFrameRenderer.to_mimebundle(self, fig_dict) 575 if not isdir(self.html_directory): 576 raise --> 578 write_html( 579 fig_dict, 580 filename, 581 config=self.config, 582 auto_play=self.auto_play, 583 include_plotlyjs=self.include_plotlyjs, 584 include_mathjax="cdn", 585 auto_open=False, 586 post_script=self.post_script, 587 animation_opts=self.animation_opts, 588 default_width="100%", 589 default_height=525, 590 validate=False, 591 ) 593 # Build IFrame 594 iframe_html = """\ 595