Save pandas dataframe as image

Is there a way to save a dataframe as an image or a pdf?
I’m using the pandas pivot_table() to produce the output table that I need, and I’m using style.apply() to make conditional formatting on the table.
Outside Anvil I can use the package ‘dataframe_image’ to export the table as an image.
Is it possible to do something similar in Anvil?

I have only been able to find info on saving plots as an image. But since I have a dataframe and not a plot, I don’t think I can use that approach. Any Advice?

Here is my python code which I use outside Anvil:

pivot_table = df.pivot_table(index=[‘gruppe’, ‘barn_nr’],
columns=‘dato’,
values=‘barn’,
aggfunc=lambda x: ’ '.join(x)).reindex(columns=datoer)
host_pivot = df.pivot_table(index=[‘gruppe’, ‘barn_nr’],
columns=‘dato’,
values=‘vært’).reindex(columns=datoer)

s = pivot_table.style.apply(lambda _: (host_pivot == 1).replace({True: 'background-color:green', False: ''}), axis=None)
for idx, group_df in pivot_table.groupby('gruppe'):
    s.set_table_styles({group_df.index[0]: [{'selector': '', 'props': 'border-top: 1px solid black;'}]},
                       overwrite=False, axis=1)
dfi.export(s, "final.png")

You could figure out some way to make the current package you use, work with Anvil…

Or you could just turn your data frame output into an iterable object that a datagrid could digest and create an Anvil form to load and display the data, then transform the form into a pdf all inside Anvil without any external tools.

It’s not that through Anvil it would be simpler or “better”, just that it is more battle-tested, and there is more help regarding the topic if you went that path.

Edit:
Or you could use uplink, and only pass the fraction of the data you want turned into an image, then use dataframe_image on another machine. Passing a media object back to Anvil.
(I’m assuming you dont want to turn 10’s of thousands of rows into a png…)

Thanks for the quick reply. The dataframe table I’m producing is quite small, so it will always be fine as a PNG. So that is no problem.
Will I be able to do conditional formatting, i.e. something like apply.style(), on the cells in the table if I use the datagrid/form approach?
I know about the uplink possibility but as far as I know the app would only work if my pc is turned on, so that is not the best solution.

Another alternative…
Are you using free anvil, or the full python version (one of the paid plans)?

There is a new feature in the beta editor where you can add your own pipy (pip) packages to anvil.

Maybe you can install dataframe_image using this feature?

If that does not work and you are a paid user you could try emailing anvil support and asking them to add it, this sounds like a pretty useful package to have installed.

1 Like

Thanks a lot.
I’m using the paid version. I have now tried to pip install ‘dataframe_image’. But I get an error message (“Error – image size limit exceeded”) during the installation. I have sent an email to support@anvil.works. Hopefully they can install it or give guidance to an alternative. I’ll post the solution here when I know more.

1 Like

Have you tried displaying your ‘s’ data in a repeating panel, and then rendering that display as a PDF?

You can layout and style the repeating panel to display the data in any format you prefer, as well as build a nice surrounding page presentation to explain or display anything else you want about the data. You don’t ever need to display the page that’s rendered to PDF - just call it with any arguments you need (your data), and then render and download (or save to data table, email, etc.).

I’m quite a newbie here, so maybe I’m misunderstanding something.
Can I style the individual cells in the repeating panel dynamically? I’m currently using apply.style() to do some conditional formatting on the dataframe before saving as an image. E.g. green background fill based on the cell value of another similar dataframe.

@cmonsted Yes, things can be dynamically styled, however you would have to learn a few more skills that are more like creating an anvil app form than the quick use of something like apply.style()

While you wait for support, you could check out how repeating panels and data grids work, there are lots of posts and Tutorials on how to do it, you might find it much simpler than you would think.

(Most people struggle with the iterable data part, but you seem to already have that knowledge)

Once you know how, creating an entire app around this concept can take 10-30 minutes, and you can reuse the concepts and code in other places.

1 Like

Maybe this example will help:

https://anvil.works/build#clone:XM6UBRJJBPTN55EH=RKSB6IKJKEIFZIN5VNMCQMSS

BTW, if you’re going to render many thousands of lines to PDF, you’d probably want to move the create_pdf() function to a background task.