dexplo/dataframe_image

AttributeError: 'ColormapRegistry' object has no attribute 'get_cmap'

LysSanzMoreta opened this issue ยท 19 comments

Whops, I cannot use the background_gradient styler while also exporting because I get the following error:

Packages versions:

Python 3.8.13
Dataframe_image 0.1.5
Matplotlib 3.6.0
Pandas: 1.5.2

Code to reproduce error:

import pandas as pd
import dataframe_image as dfi
aa_dict = {"A":{"a1":1,"a2":2},"B":{"a1":3,"a2":4}}
df = pd.DataFrame.from_dict(aa_dict)
df_styled = df.style.background_gradient(axis=None)
dfi.export(df_styled,"df_experiment.png",dpi=600)

Error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lys/miniconda3/lib/python3.8/site-packages/dataframe_image/_pandas_accessor.py", line 48, in export
    return _export(
  File "/home/lys/miniconda3/lib/python3.8/site-packages/dataframe_image/_pandas_accessor.py", line 113, in _export
    html = styler2html(obj)
  File "/home/lys/miniconda3/lib/python3.8/site-packages/dataframe_image/pd_html.py", line 8, in styler2html
    html = style.to_html()
  File "/home/lys/miniconda3/lib/python3.8/site-packages/pandas/io/formats/style.py", line 1371, in to_html
    html = obj._render_html(
  File "/home/lys/miniconda3/lib/python3.8/site-packages/pandas/io/formats/style_render.py", line 199, in _render_html
    d = self._render(sparse_index, sparse_columns, max_rows, max_cols, "&nbsp;")
  File "/home/lys/miniconda3/lib/python3.8/site-packages/pandas/io/formats/style_render.py", line 163, in _render
    self._compute()
  File "/home/lys/miniconda3/lib/python3.8/site-packages/pandas/io/formats/style_render.py", line 251, in _compute
    r = func(self)(*args, **kwargs)
  File "/home/lys/miniconda3/lib/python3.8/site-packages/pandas/io/formats/style.py", line 1713, in _apply
    result = func(data, **kwargs)
  File "/home/lys/miniconda3/lib/python3.8/site-packages/pandas/io/formats/style.py", line 3936, in _background_gradient
    rgbas = mpl.colormaps.get_cmap(cmap)(norm(gmap))
AttributeError: 'ColormapRegistry' object has no attribute 'get_cmap'

Side note: i can export if I do not use the background_gradient styler

Thanks!!!

I think it is not a problem related to dfi.

Try replace the last line with:

df_styled.to_html()

And see if the same error occors.

Hi!
I think I had already tried something similar and did not work. I gave it a try anyways (if this is what you mean...):

import pandas as pd
import dataframe_image as dfi
aa_dict = {"A":{"a1":1,"a2":2},"B":{"a1":3,"a2":4}}
df = pd.DataFrame.from_dict(aa_dict)
df_styled = df.style.background_gradient(axis=None)
dfi.export(df_styled.to_html(),"df_experiment.png",dpi=600)

And the error is the same

Thanks!

Hi! I think I had already tried something similar and did not work. I gave it a try anyways (if this is what you mean...):

import pandas as pd
import dataframe_image as dfi
aa_dict = {"A":{"a1":1,"a2":2},"B":{"a1":3,"a2":4}}
df = pd.DataFrame.from_dict(aa_dict)
df_styled = df.style.background_gradient(axis=None)
dfi.export(df_styled.to_html(),"df_experiment.png",dpi=600)

And the error is the same

Thanks!

I mean to html without dfi. I think this error is not related to this module.

import pandas as pd

aa_dict = {"A":{"a1":1,"a2":2},"B":{"a1":3,"a2":4}}
df = pd.DataFrame.from_dict(aa_dict)
df_styled = df.style.background_gradient(axis=None)
df_styled.to_html()

Oh, ok, yes sorry for the confusion. I did it correctly now and get the same error, indeed.

Is it a pandas.style.to_html() issue then? Should I report it to them?

Thanks!

I never heard a problem about this, maybe you need to confirm your env first.

Ok, just to confirm, do you want to check the "environment" as in all the installed packages? Or else?

On-ryo commented

I have the same problem with this code:
Correlation function itself works well

corr = df.corr(method='spearman', min_periods=3, numeric_only = True)
corr.style.background_gradient(cmap='coolwarm')

Have you solved this problem?

I have the same problem with this code: Correlation function itself works well

corr = df.corr(method='spearman', min_periods=3, numeric_only = True)
corr.style.background_gradient(cmap='coolwarm')

Have you solved this problem?

@huo-shan-long At that time I simply just solved it by "not using the background_gradient styler". I need this functionality again, so I will see if things have changed.

I have upgraded dataframe_image to 0.1.11 with the same issue

Working on a work-around

@huo-shan-long @On-ryo @PaleNeutron Ok. I found a work-around. If you manually modify the function _background_gradient() in this script in the pandas package .../python3.8/site-packages/pandas/io/formats/style.df:

Like this:

        if mpl_ge_3_6_0():
            if cmap is None:
                try:
                    rgbas = mpl.colormaps[mpl.rcParams["image.cmap"]](norm(gmap))
                except:
                    rgbas = plt.cm.get_cmap(cmap)(norm(gmap))
            else:
                try:
                    rgbas = mpl.colormaps.get_cmap(cmap)(norm(gmap))
                except:
                    rgbas = plt.cm.get_cmap(cmap)(norm(gmap)) #this works
        else:
            rgbas = plt.cm.get_cmap(cmap)(norm(gmap))

There seems to be a bug on some matplotlib compatibility. I used the ugly try-except combo because I am not sure if the condition if mpl_ge_3_6_0() is important in another context. Otherwise I would just remove that.

@huo-shan-long @On-ryo @PaleNeutron Ok. I found a work-around. If you manually modify the function _background_gradient() in this script in the pandas package .../python3.8/site-packages/pandas/io/formats/style.df:

Like this:

        if mpl_ge_3_6_0():
            if cmap is None:
                try:
                    rgbas = mpl.colormaps[mpl.rcParams["image.cmap"]](norm(gmap))
                except:
                    rgbas = plt.cm.get_cmap(cmap)(norm(gmap))
            else:
                try:
                    rgbas = mpl.colormaps.get_cmap(cmap)(norm(gmap))
                except:
                    rgbas = plt.cm.get_cmap(cmap)(norm(gmap)) #this works
        else:
            rgbas = plt.cm.get_cmap(cmap)(norm(gmap))

There seems to be a bug on some matplotlib compatibility. I used the ugly try-except combo because I am not sure if the condition if mpl_ge_3_6_0() is important in another context. Otherwise I would just remove that.

I solved the problem, the pandas version at the beginning was 2.0.2, after I downgraded version it to 1.5.3, it worked.

@huo-shan-long yeah, it is a version problem, but if you do not want to downgrade, the previous works

@huo-shan-long @On-ryo @PaleNeutron Ok. I found a work-around. If you manually modify the function _background_gradient() in this script in the pandas package .../python3.8/site-packages/pandas/io/formats/style.df:

Like this:

        if mpl_ge_3_6_0():
            if cmap is None:
                try:
                    rgbas = mpl.colormaps[mpl.rcParams["image.cmap"]](norm(gmap))
                except:
                    rgbas = plt.cm.get_cmap(cmap)(norm(gmap))
            else:
                try:
                    rgbas = mpl.colormaps.get_cmap(cmap)(norm(gmap))
                except:
                    rgbas = plt.cm.get_cmap(cmap)(norm(gmap)) #this works
        else:
            rgbas = plt.cm.get_cmap(cmap)(norm(gmap))

There seems to be a bug on some matplotlib compatibility. I used the ugly try-except combo because I am not sure if the condition if mpl_ge_3_6_0() is important in another context. Otherwise I would just remove that.

Congratulations! Is there any thing I should modify in dataframe_image ?

@PaleNeutron Hmm, perhaps recommend a lower version of pandas? like a warning?, I would not enforce a downgrade.
Or change the cmap type before feeding it to pandas?

@LysSanzMoreta I had the same error under pandas 2.1.0. In my case, an update of matplotlib and seaborn to the newest version solved it. So it was related to these libraries, and not the pandas, indeed. Hope this helps.

I have the same problem with this code: Correlation function itself works well

corr = df.corr(method='spearman', min_periods=3, numeric_only = True)
corr.style.background_gradient(cmap='coolwarm')

I am having this same problem right now. corr is working.

A simple way to solve this problem without editing libraries is just to set "image.cmap" of your choice:

plt.rcParams["image.cmap"] = 'Blues'

and when call 'background_gradient':

.style.background_gradient(cmap=None)

@LysSanzMoreta , sorry not to mention you above! You are right that the problem cause is versioning.

But it is the better way to solve the problem in your code, not in the library #74 (comment).