dexplo / dataframe_image

A python package for embedding pandas DataFrames as images into pdf and markdown documents
https://dexplo.org/dataframe_image
MIT License
282 stars 41 forks source link

Wrapping long text in exported images #83

Closed jonnyzwi closed 1 year ago

jonnyzwi commented 1 year ago

Is there a way to have exported DF images wrap long text?

I am able to properly set the width property of the styled_df with:

styled_df = df.style.set_properties(subset=['Long Text'], **{'width': '20em'})

It displays properly in my notebook, but the exported DF image always results in extremely wide columns to accommodate long text—effectively ignoring the style properties that I know I set.

The result is that the exported image is not usable in my situation

Thanks for any help.

PaleNeutron commented 1 year ago

Use px instead of em and have see if works.

jonnyzwi commented 1 year ago

Unfortunately that does not help. Any other ideas?

PaleNeutron commented 1 year ago

Can you provide a minimal test script?

ndalchau commented 1 year ago

I have the same problem. Here is a minimal example:

import dataframe_image as dfi
import pandas as pd

df = pd.DataFrame({"My long column name that I want to wrap": [1, 2, 3, 4], "Another column": [2, 3, 4, 5]})
styled = df.style.set_properties(subset=df.columns, **{'width': '90px'})

dfi.export(styled, "output.png", table_conversion="matplotlib")

Here is what I get in Jupyter: image

Here is what gets exported: output

PaleNeutron commented 1 year ago

@ndalchau For short, please add '\n' manully.

  df = pd.DataFrame({"My long\ncolumn name\nthat I want to wrap": [1, 2, 3, 4], "Another column": [2, 3, 4, 5]})
  styled = df.style.set_properties(subset=df.columns, **{'width': '90px'})

  dfi.export(styled, "output.png", table_conversion="matplotlib")

output

Long reason:

Current matplotlib method is just for some very simple case or user can not install any browser somehow. We get some key information from html and draw it by matplotlib not 'render' html so most css won't be supported.

For this case:

Column width in matplotlib method is calculated by

https://github.com/dexplo/dataframe_image/blob/570fe8df9fcd140fa5db98b0e244fc2e05d18647/dataframe_image/converter/matplotlib_table.py#L174-L198

You can see it is nothing with css. If we want to support all css, it will be some kind of "reimplement a webkit".

I suggest: if you only want to wrap long headers. write a function automatically add '\n' to your dataframe headers or use any browser-based convert method to get 1:1 same picture.

ndalchau commented 1 year ago

Thanks, that makes sense. I'll not try and use CSS with this library. I think this issue can be closed now.