8
8
import copy
9
9
from functools import partial
10
10
from itertools import product
11
+ from typing import Optional
11
12
from uuid import uuid1
12
13
13
14
import numpy as np
18
19
from pandas .util ._decorators import Appender
19
20
20
21
from pandas .core .dtypes .common import is_float , is_string_like
21
- from pandas .core .dtypes .generic import ABCSeries
22
22
23
23
import pandas as pd
24
24
from pandas .api .types import is_dict_like , is_list_like
@@ -963,6 +963,8 @@ def background_gradient(
963
963
axis = 0 ,
964
964
subset = None ,
965
965
text_color_threshold = 0.408 ,
966
+ vmin : Optional [float ] = None ,
967
+ vmax : Optional [float ] = None ,
966
968
):
967
969
"""
968
970
Color the background in a gradient style.
@@ -991,6 +993,18 @@ def background_gradient(
991
993
992
994
.. versionadded:: 0.24.0
993
995
996
+ vmin : float, optional
997
+ Minimum data value that corresponds to colormap minimum value.
998
+ When None (default): the minimum value of the data will be used.
999
+
1000
+ .. versionadded:: 1.0.0
1001
+
1002
+ vmax : float, optional
1003
+ Maximum data value that corresponds to colormap maximum value.
1004
+ When None (default): the maximum value of the data will be used.
1005
+
1006
+ .. versionadded:: 1.0.0
1007
+
994
1008
Returns
995
1009
-------
996
1010
self : Styler
@@ -1017,11 +1031,21 @@ def background_gradient(
1017
1031
low = low ,
1018
1032
high = high ,
1019
1033
text_color_threshold = text_color_threshold ,
1034
+ vmin = vmin ,
1035
+ vmax = vmax ,
1020
1036
)
1021
1037
return self
1022
1038
1023
1039
@staticmethod
1024
- def _background_gradient (s , cmap = "PuBu" , low = 0 , high = 0 , text_color_threshold = 0.408 ):
1040
+ def _background_gradient (
1041
+ s ,
1042
+ cmap = "PuBu" ,
1043
+ low = 0 ,
1044
+ high = 0 ,
1045
+ text_color_threshold = 0.408 ,
1046
+ vmin : Optional [float ] = None ,
1047
+ vmax : Optional [float ] = None ,
1048
+ ):
1025
1049
"""
1026
1050
Color background in a range according to the data.
1027
1051
"""
@@ -1033,14 +1057,14 @@ def _background_gradient(s, cmap="PuBu", low=0, high=0, text_color_threshold=0.4
1033
1057
raise ValueError (msg )
1034
1058
1035
1059
with _mpl (Styler .background_gradient ) as (plt , colors ):
1036
- smin = s . values . min ()
1037
- smax = s . values . max ()
1060
+ smin = np . nanmin ( s . to_numpy ()) if vmin is None else vmin
1061
+ smax = np . nanmax ( s . to_numpy ()) if vmax is None else vmax
1038
1062
rng = smax - smin
1039
1063
# extend lower / upper bounds, compresses color range
1040
1064
norm = colors .Normalize (smin - (rng * low ), smax + (rng * high ))
1041
1065
# matplotlib colors.Normalize modifies inplace?
1042
1066
# https://github.com/matplotlib/matplotlib/issues/5427
1043
- rgbas = plt .cm .get_cmap (cmap )(norm (s .values ))
1067
+ rgbas = plt .cm .get_cmap (cmap )(norm (s .to_numpy ( dtype = float ) ))
1044
1068
1045
1069
def relative_luminance (rgba ):
1046
1070
"""
@@ -1111,12 +1135,8 @@ def _bar(s, align, colors, width=100, vmin=None, vmax=None):
1111
1135
Draw bar chart in dataframe cells.
1112
1136
"""
1113
1137
# Get input value range.
1114
- smin = s .min () if vmin is None else vmin
1115
- if isinstance (smin , ABCSeries ):
1116
- smin = smin .min ()
1117
- smax = s .max () if vmax is None else vmax
1118
- if isinstance (smax , ABCSeries ):
1119
- smax = smax .max ()
1138
+ smin = np .nanmin (s .to_numpy ()) if vmin is None else vmin
1139
+ smax = np .nanmax (s .to_numpy ()) if vmax is None else vmax
1120
1140
if align == "mid" :
1121
1141
smin = min (0 , smin )
1122
1142
smax = max (0 , smax )
@@ -1125,7 +1145,7 @@ def _bar(s, align, colors, width=100, vmin=None, vmax=None):
1125
1145
smax = max (abs (smin ), abs (smax ))
1126
1146
smin = - smax
1127
1147
# Transform to percent-range of linear-gradient
1128
- normed = width * (s .values - smin ) / (smax - smin + 1e-12 )
1148
+ normed = width * (s .to_numpy ( dtype = float ) - smin ) / (smax - smin + 1e-12 )
1129
1149
zero = - width * smin / (smax - smin + 1e-12 )
1130
1150
1131
1151
def css_bar (start , end , color ):
@@ -1304,17 +1324,15 @@ def _highlight_extrema(data, color="yellow", max_=True):
1304
1324
Highlight the min or max in a Series or DataFrame.
1305
1325
"""
1306
1326
attr = "background-color: {0}" .format (color )
1327
+
1328
+ if max_ :
1329
+ extrema = data == np .nanmax (data .to_numpy ())
1330
+ else :
1331
+ extrema = data == np .nanmin (data .to_numpy ())
1332
+
1307
1333
if data .ndim == 1 : # Series from .apply
1308
- if max_ :
1309
- extrema = data == data .max ()
1310
- else :
1311
- extrema = data == data .min ()
1312
1334
return [attr if v else "" for v in extrema ]
1313
1335
else : # DataFrame from .tee
1314
- if max_ :
1315
- extrema = data == data .max ().max ()
1316
- else :
1317
- extrema = data == data .min ().min ()
1318
1336
return pd .DataFrame (
1319
1337
np .where (extrema , attr , "" ), index = data .index , columns = data .columns
1320
1338
)
0 commit comments