@@ -23,258 +23,20 @@ def no_bar():
23
23
return bar_grad ()
24
24
25
25
26
- def bar_to (x ):
27
- return bar_grad (f" #d65f5f { x :.1f} %" , f" transparent { x :.1f} %" )
26
+ def bar_to (x , color = "#d65f5f" ):
27
+ return bar_grad (f" { color } { x :.1f} %" , f" transparent { x :.1f} %" )
28
28
29
29
30
- def bar_from_to (x , y ):
30
+ def bar_from_to (x , y , color = "#d65f5f" ):
31
31
return bar_grad (
32
32
f" transparent { x :.1f} %" ,
33
- f" #d65f5f { x :.1f} %" ,
34
- f" #d65f5f { y :.1f} %" ,
33
+ f" { color } { x :.1f} %" ,
34
+ f" { color } { y :.1f} %" ,
35
35
f" transparent { y :.1f} %" ,
36
36
)
37
37
38
38
39
39
class TestStylerBarAlign :
40
- def test_bar_align_left (self ):
41
- df = DataFrame ({"A" : [0 , 1 , 2 ]})
42
- result = df .style .bar (align = "left" )._compute ().ctx
43
- expected = {
44
- (0 , 0 ): bar_grad (),
45
- (1 , 0 ): bar_grad (" #d65f5f 50.0%" , " transparent 50.0%" ),
46
- (2 , 0 ): bar_grad (" #d65f5f 100.0%" , " transparent 100.0%" ),
47
- }
48
- assert result == expected
49
-
50
- result = df .style .bar (color = "red" , width = 50 , align = "left" )._compute ().ctx
51
- expected = {
52
- (0 , 0 ): bar_grad (),
53
- (1 , 0 ): bar_grad (" red 25.0%" , " transparent 25.0%" ),
54
- (2 , 0 ): bar_grad (" red 50.0%" , " transparent 50.0%" ),
55
- }
56
- assert result == expected
57
-
58
- df ["C" ] = ["a" ] * len (df )
59
- result = df .style .bar (color = "red" , width = 50 , align = "left" )._compute ().ctx
60
- assert result == expected
61
- df ["C" ] = df ["C" ].astype ("category" )
62
- result = df .style .bar (color = "red" , width = 50 , align = "left" )._compute ().ctx
63
- assert result == expected
64
-
65
- def test_bar_align_left_0points (self ):
66
- df = DataFrame ([[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ]])
67
- result = df .style .bar (align = "left" )._compute ().ctx
68
- expected = {
69
- (0 , 0 ): bar_grad (),
70
- (0 , 1 ): bar_grad (),
71
- (0 , 2 ): bar_grad (),
72
- (1 , 0 ): bar_grad (" #d65f5f 50.0%" , " transparent 50.0%" ),
73
- (1 , 1 ): bar_grad (" #d65f5f 50.0%" , " transparent 50.0%" ),
74
- (1 , 2 ): bar_grad (" #d65f5f 50.0%" , " transparent 50.0%" ),
75
- (2 , 0 ): bar_grad (" #d65f5f 100.0%" , " transparent 100.0%" ),
76
- (2 , 1 ): bar_grad (" #d65f5f 100.0%" , " transparent 100.0%" ),
77
- (2 , 2 ): bar_grad (" #d65f5f 100.0%" , " transparent 100.0%" ),
78
- }
79
- assert result == expected
80
-
81
- result = df .style .bar (axis = 1 , align = "left" )._compute ().ctx
82
- expected = {
83
- (0 , 0 ): bar_grad (),
84
- (0 , 1 ): bar_grad (" #d65f5f 50.0%" , " transparent 50.0%" ),
85
- (0 , 2 ): bar_grad (" #d65f5f 100.0%" , " transparent 100.0%" ),
86
- (1 , 0 ): bar_grad (),
87
- (1 , 1 ): bar_grad (" #d65f5f 50.0%" , " transparent 50.0%" ),
88
- (1 , 2 ): bar_grad (" #d65f5f 100.0%" , " transparent 100.0%" ),
89
- (2 , 0 ): bar_grad (),
90
- (2 , 1 ): bar_grad (" #d65f5f 50.0%" , " transparent 50.0%" ),
91
- (2 , 2 ): bar_grad (" #d65f5f 100.0%" , " transparent 100.0%" ),
92
- }
93
- assert result == expected
94
-
95
- def test_bar_align_mid_pos_and_neg (self ):
96
- df = DataFrame ({"A" : [- 10 , 0 , 20 , 90 ]})
97
- result = df .style .bar (align = "mid" , color = ["#d65f5f" , "#5fba7d" ])._compute ().ctx
98
- expected = {
99
- (0 , 0 ): bar_grad (
100
- " #d65f5f 10.0%" ,
101
- " transparent 10.0%" ,
102
- ),
103
- (1 , 0 ): bar_grad (),
104
- (2 , 0 ): bar_grad (
105
- " transparent 10.0%" ,
106
- " #5fba7d 10.0%" ,
107
- " #5fba7d 30.0%" ,
108
- " transparent 30.0%" ,
109
- ),
110
- (3 , 0 ): bar_grad (
111
- " transparent 10.0%" ,
112
- " #5fba7d 10.0%" ,
113
- " #5fba7d 100.0%" ,
114
- " transparent 100.0%" ,
115
- ),
116
- }
117
- assert result == expected
118
-
119
- def test_bar_align_mid_all_pos (self ):
120
- df = DataFrame ({"A" : [10 , 20 , 50 , 100 ]})
121
-
122
- result = df .style .bar (align = "mid" , color = ["#d65f5f" , "#5fba7d" ])._compute ().ctx
123
-
124
- expected = {
125
- (0 , 0 ): bar_grad (
126
- " #5fba7d 10.0%" ,
127
- " transparent 10.0%" ,
128
- ),
129
- (1 , 0 ): bar_grad (
130
- " #5fba7d 20.0%" ,
131
- " transparent 20.0%" ,
132
- ),
133
- (2 , 0 ): bar_grad (
134
- " #5fba7d 50.0%" ,
135
- " transparent 50.0%" ,
136
- ),
137
- (3 , 0 ): bar_grad (
138
- " #5fba7d 100.0%" ,
139
- " transparent 100.0%" ,
140
- ),
141
- }
142
-
143
- assert result == expected
144
-
145
- def test_bar_align_mid_all_neg (self ):
146
- df = DataFrame ({"A" : [- 100 , - 60 , - 30 , - 20 ]})
147
-
148
- result = df .style .bar (align = "mid" , color = ["#d65f5f" , "#5fba7d" ])._compute ().ctx
149
-
150
- expected = {
151
- (0 , 0 ): bar_grad (
152
- " #d65f5f 100.0%" ,
153
- " transparent 100.0%" ,
154
- ),
155
- (1 , 0 ): bar_grad (
156
- " transparent 40.0%" ,
157
- " #d65f5f 40.0%" ,
158
- " #d65f5f 100.0%" ,
159
- " transparent 100.0%" ,
160
- ),
161
- (2 , 0 ): bar_grad (
162
- " transparent 70.0%" ,
163
- " #d65f5f 70.0%" ,
164
- " #d65f5f 100.0%" ,
165
- " transparent 100.0%" ,
166
- ),
167
- (3 , 0 ): bar_grad (
168
- " transparent 80.0%" ,
169
- " #d65f5f 80.0%" ,
170
- " #d65f5f 100.0%" ,
171
- " transparent 100.0%" ,
172
- ),
173
- }
174
- assert result == expected
175
-
176
- def test_bar_align_zero_pos_and_neg (self ):
177
- # See https://github.com/pandas-dev/pandas/pull/14757
178
- df = DataFrame ({"A" : [- 10 , 0 , 20 , 90 ]})
179
-
180
- result = (
181
- df .style .bar (align = "zero" , color = ["#d65f5f" , "#5fba7d" ], width = 90 )
182
- ._compute ()
183
- .ctx
184
- )
185
- expected = {
186
- (0 , 0 ): bar_grad (
187
- " transparent 40.0%" ,
188
- " #d65f5f 40.0%" ,
189
- " #d65f5f 45.0%" ,
190
- " transparent 45.0%" ,
191
- ),
192
- (1 , 0 ): bar_grad (),
193
- (2 , 0 ): bar_grad (
194
- " transparent 45.0%" ,
195
- " #5fba7d 45.0%" ,
196
- " #5fba7d 55.0%" ,
197
- " transparent 55.0%" ,
198
- ),
199
- (3 , 0 ): bar_grad (
200
- " transparent 45.0%" ,
201
- " #5fba7d 45.0%" ,
202
- " #5fba7d 90.0%" ,
203
- " transparent 90.0%" ,
204
- ),
205
- }
206
- assert result == expected
207
-
208
- def test_bar_align_left_axis_none (self ):
209
- df = DataFrame ({"A" : [0 , 1 ], "B" : [2 , 4 ]})
210
- result = df .style .bar (axis = None , align = "left" )._compute ().ctx
211
- expected = {
212
- (0 , 0 ): bar_grad (),
213
- (1 , 0 ): bar_grad (
214
- " #d65f5f 25.0%" ,
215
- " transparent 25.0%" ,
216
- ),
217
- (0 , 1 ): bar_grad (
218
- " #d65f5f 50.0%" ,
219
- " transparent 50.0%" ,
220
- ),
221
- (1 , 1 ): bar_grad (
222
- " #d65f5f 100.0%" ,
223
- " transparent 100.0%" ,
224
- ),
225
- }
226
- assert result == expected
227
-
228
- def test_bar_align_zero_axis_none (self ):
229
- df = DataFrame ({"A" : [0 , 1 ], "B" : [- 2 , 4 ]})
230
- result = df .style .bar (align = "zero" , axis = None )._compute ().ctx
231
- expected = {
232
- (0 , 0 ): bar_grad (),
233
- (1 , 0 ): bar_grad (
234
- " transparent 50.0%" ,
235
- " #d65f5f 50.0%" ,
236
- " #d65f5f 62.5%" ,
237
- " transparent 62.5%" ,
238
- ),
239
- (0 , 1 ): bar_grad (
240
- " transparent 25.0%" ,
241
- " #d65f5f 25.0%" ,
242
- " #d65f5f 50.0%" ,
243
- " transparent 50.0%" ,
244
- ),
245
- (1 , 1 ): bar_grad (
246
- " transparent 50.0%" ,
247
- " #d65f5f 50.0%" ,
248
- " #d65f5f 100.0%" ,
249
- " transparent 100.0%" ,
250
- ),
251
- }
252
- assert result == expected
253
-
254
- def test_bar_align_mid_axis_none (self ):
255
- df = DataFrame ({"A" : [0 , 1 ], "B" : [- 2 , 4 ]})
256
- result = df .style .bar (align = "mid" , axis = None )._compute ().ctx
257
- expected = {
258
- (0 , 0 ): bar_grad (),
259
- (1 , 0 ): bar_grad (
260
- " transparent 33.3%" ,
261
- " #d65f5f 33.3%" ,
262
- " #d65f5f 50.0%" ,
263
- " transparent 50.0%" ,
264
- ),
265
- (0 , 1 ): bar_grad (
266
- " #d65f5f 33.3%" ,
267
- " transparent 33.3%" ,
268
- ),
269
- (1 , 1 ): bar_grad (
270
- " transparent 33.3%" ,
271
- " #d65f5f 33.3%" ,
272
- " #d65f5f 100.0%" ,
273
- " transparent 100.0%" ,
274
- ),
275
- }
276
- assert result == expected
277
-
278
40
def test_bar_align_mid_vmin (self ):
279
41
df = DataFrame ({"A" : [0 , 1 ], "B" : [- 2 , 4 ]})
280
42
result = df .style .bar (align = "mid" , axis = None , vmin = - 6 )._compute ().ctx
@@ -438,7 +200,7 @@ def test_bar_bad_align_raises(self):
438
200
(np .median , [bar_to (50 ), no_bar (), bar_from_to (50 , 100 )]),
439
201
],
440
202
)
441
- def test_bar_align_positive_cases (align , exp ):
203
+ def test_align_positive_cases (align , exp ):
442
204
# test different align cases for all positive values
443
205
data = DataFrame ([[1 ], [2 ], [3 ]])
444
206
result = data .style .bar (align = align )._compute ().ctx
@@ -458,7 +220,7 @@ def test_bar_align_positive_cases(align, exp):
458
220
(np .median , [bar_from_to (50 , 100 ), no_bar (), bar_to (50 )]),
459
221
],
460
222
)
461
- def test_bar_align_negative_cases (align , exp ):
223
+ def test_align_negative_cases (align , exp ):
462
224
# test different align cases for all negative values
463
225
data = DataFrame ([[- 1 ], [- 2 ], [- 3 ]])
464
226
result = data .style .bar (align = align )._compute ().ctx
@@ -478,9 +240,105 @@ def test_bar_align_negative_cases(align, exp):
478
240
(np .median , [bar_to (50 ), no_bar (), bar_from_to (50 , 62.5 )]),
479
241
],
480
242
)
481
- def test_bar_align_mixed_cases (align , exp ):
243
+ def test_align_mixed_cases (align , exp ):
482
244
# test different align cases for mixed positive and negative values
483
245
data = DataFrame ([[- 3 ], [1 ], [2 ]])
484
246
result = data .style .bar (align = align )._compute ().ctx
485
247
expected = {(0 , 0 ): exp [0 ], (1 , 0 ): exp [1 ], (2 , 0 ): exp [2 ]}
486
248
assert result == expected
249
+
250
+
251
+ @pytest .mark .parametrize (
252
+ "align, exp" ,
253
+ [
254
+ (
255
+ "left" ,
256
+ {
257
+ "index" : [[no_bar (), no_bar ()], [bar_to (100 ), bar_to (100 )]],
258
+ "columns" : [[no_bar (), bar_to (100 )], [no_bar (), bar_to (100 )]],
259
+ "none" : [[no_bar (), bar_to (33.33 )], [bar_to (66.66 ), bar_to (100 )]],
260
+ },
261
+ ),
262
+ (
263
+ "mid" ,
264
+ {
265
+ "index" : [[bar_to (33.33 ), bar_to (50 )], [bar_to (100 ), bar_to (100 )]],
266
+ "columns" : [[bar_to (50 ), bar_to (100 )], [bar_to (75 ), bar_to (100 )]],
267
+ "none" : [[bar_to (25 ), bar_to (50 )], [bar_to (75 ), bar_to (100 )]],
268
+ },
269
+ ),
270
+ (
271
+ "zero" ,
272
+ {
273
+ "index" : [
274
+ [bar_from_to (50 , 66.66 ), bar_from_to (50 , 75 )],
275
+ [bar_from_to (50 , 100 ), bar_from_to (50 , 100 )],
276
+ ],
277
+ "columns" : [
278
+ [bar_from_to (50 , 75 ), bar_from_to (50 , 100 )],
279
+ [bar_from_to (50 , 87.5 ), bar_from_to (50 , 100 )],
280
+ ],
281
+ "none" : [
282
+ [bar_from_to (50 , 62.5 ), bar_from_to (50 , 75 )],
283
+ [bar_from_to (50 , 87.5 ), bar_from_to (50 , 100 )],
284
+ ],
285
+ },
286
+ ),
287
+ (
288
+ 2 ,
289
+ {
290
+ "index" : [
291
+ [bar_to (50 ), no_bar ()],
292
+ [bar_from_to (50 , 100 ), bar_from_to (50 , 100 )],
293
+ ],
294
+ "columns" : [
295
+ [bar_to (50 ), no_bar ()],
296
+ [bar_from_to (50 , 75 ), bar_from_to (50 , 100 )],
297
+ ],
298
+ "none" : [
299
+ [bar_from_to (25 , 50 ), no_bar ()],
300
+ [bar_from_to (50 , 75 ), bar_from_to (50 , 100 )],
301
+ ],
302
+ },
303
+ ),
304
+ ],
305
+ )
306
+ @pytest .mark .parametrize ("axis" , ["index" , "columns" , "none" ])
307
+ def test_align_axis (align , exp , axis ):
308
+ # test all axis combinations with positive values and different aligns
309
+ data = DataFrame ([[1 , 2 ], [3 , 4 ]])
310
+ result = (
311
+ data .style .bar (align = align , axis = None if axis == "none" else axis )
312
+ ._compute ()
313
+ .ctx
314
+ )
315
+ expected = {
316
+ (0 , 0 ): exp [axis ][0 ][0 ],
317
+ (0 , 1 ): exp [axis ][0 ][1 ],
318
+ (1 , 0 ): exp [axis ][1 ][0 ],
319
+ (1 , 1 ): exp [axis ][1 ][1 ],
320
+ }
321
+ assert result == expected
322
+
323
+
324
+ def test_numerics ():
325
+ # test data is pre-selected for numeric values
326
+ data = DataFrame ([[1 , "a" ], [2 , "b" ]])
327
+ result = data .style .bar ()._compute ().ctx
328
+ assert (0 , 1 ) not in result
329
+ assert (1 , 1 ) not in result
330
+
331
+
332
+ @pytest .mark .parametrize (
333
+ "align, exp" ,
334
+ [
335
+ ("left" , [no_bar (), bar_to (100 , "green" )]),
336
+ ("right" , [bar_to (100 , "red" ), no_bar ()]),
337
+ ("mid" , [bar_to (25 , "red" ), bar_from_to (25 , 100 , "green" )]),
338
+ ("zero" , [bar_from_to (33.33 , 50 , "red" ), bar_from_to (50 , 100 , "green" )]),
339
+ ],
340
+ )
341
+ def test_colors_mixed (align , exp ):
342
+ data = DataFrame ([[- 1 ], [3 ]])
343
+ result = data .style .bar (align = align , color = ["red" , "green" ])._compute ().ctx
344
+ assert result == {(0 , 0 ): exp [0 ], (1 , 0 ): exp [1 ]}
0 commit comments