Skip to content

Commit 9a87c2f

Browse files
committed
Introduce "no_group" mode which applies colors/opacities to all bars
Signed-off-by: martinRenou <martin.renou@gmail.com>
1 parent f3d5c98 commit 9a87c2f

4 files changed

Lines changed: 52 additions & 17 deletions

File tree

bqplot/marks.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -966,14 +966,16 @@ class Bars(Mark):
966966
font-awesome icon for that mark
967967
name: string (class-level attribute)
968968
user-friendly name of the mark
969-
color_mode: {'auto', 'group', 'element'}
970-
enum attribute to specify if color should be the same for all bars with
971-
the same x or for all bars which belong to the same array in Y
972-
'group' means for every x all bars have same color.
973-
'element' means for every dimension of y, all bars have same color.
974-
'auto' picks 'group' and 'element' for 1-d and 2-d values of
975-
Y respectively.
976-
opacity_mode: {'auto', 'group', 'element'}
969+
color_mode: {'auto', 'group', 'element', 'no_group'}
970+
Specify how default colors are applied to bars.
971+
The 'group' mode means colors are assigned per group. If the list
972+
of colors is shorter than the number of groups, colors are reused.
973+
The 'element' mode means colors are assigned per group element. If the list
974+
of colors is shorter than the number of bars in a group, colors are reused.
975+
The 'no_group' mode means colors are assigned per bar, discarding the fact
976+
that there are groups or stacks. If the list of colors is shorter than the
977+
total number of bars, colors are reused.
978+
opacity_mode: {'auto', 'group', 'element', 'no_group'}
977979
Same as the `color_mode` attribute, but for the opacity.
978980
type: {'stacked', 'grouped'}
979981
whether 2-dimensional bar charts should appear grouped or stacked.
@@ -1061,9 +1063,9 @@ class Bars(Mark):
10611063
'y': {'orientation': 'vertical', 'dimension': 'y'},
10621064
'color': {'dimension': 'color'}
10631065
}).tag(sync=True)
1064-
color_mode = Enum(['auto', 'group', 'element'], default_value='auto')\
1066+
color_mode = Enum(['auto', 'group', 'element', 'no_group'], default_value='auto')\
10651067
.tag(sync=True)
1066-
opacity_mode = Enum(['auto', 'group', 'element'], default_value='auto')\
1068+
opacity_mode = Enum(['auto', 'group', 'element', 'no_group'], default_value='auto')\
10671069
.tag(sync=True)
10681070
type = Enum(['stacked', 'grouped'], default_value='stacked')\
10691071
.tag(sync=True, display_name='Type')

examples/Marks/Object Model/Bars.ipynb

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,10 @@
262262
"metadata": {},
263263
"outputs": [],
264264
"source": [
265-
"## Color mode has 2 values. 'group' and 'element'. \n",
266-
"## 'group' means for every x all bars have same color.\n",
267-
"## 'element' means for every dimension of y, all bars have same color.\n",
265+
"## Color mode has 3 values. 'group', 'element' and 'no_group'. \n",
266+
"## 'group' means colors are assigned per group.\n",
267+
"## 'element' means colors are assigned per group element.\n",
268+
"## 'no_group' means means colors are assigned per bar, discarding the fact that there are groups or stacks\n",
268269
"x_ord = OrdinalScale()\n",
269270
"y_sc = LinearScale()\n",
270271
"\n",
@@ -277,6 +278,24 @@
277278
"Figure(marks=[bar], axes=[ax_x, ax_y])"
278279
]
279280
},
281+
{
282+
"cell_type": "code",
283+
"execution_count": null,
284+
"metadata": {},
285+
"outputs": [],
286+
"source": [
287+
"bar.color_mode = 'element'"
288+
]
289+
},
290+
{
291+
"cell_type": "code",
292+
"execution_count": null,
293+
"metadata": {},
294+
"outputs": [],
295+
"source": [
296+
"bar.color_mode = 'no_group'"
297+
]
298+
},
280299
{
281300
"cell_type": "code",
282301
"execution_count": null,
@@ -401,7 +420,7 @@
401420
"name": "python",
402421
"nbconvert_exporter": "python",
403422
"pygments_lexer": "ipython3",
404-
"version": "3.7.4"
423+
"version": "3.8.2"
405424
}
406425
},
407426
"nbformat": 4,

js/src/Bars.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,15 @@ export class Bars extends Mark {
140140
this.draw(animate);
141141
});
142142
this.listenTo(this.model, "change:colors", this.update_colors);
143+
this.listenTo(this.model, "change:opacities", this.update_colors);
143144
this.listenTo(this.model, "colors_updated", this.update_colors);
144145
this.listenTo(this.model, "change:type", this.update_type);
145146
// FIXME: These are expensive calls for changing padding and align
146147
this.listenTo(this.model, "change:align", this.relayout);
147148
this.listenTo(this.model, "change:padding", this.relayout)
148149
this.listenTo(this.model, "change:orientation", this.relayout)
149150
this.listenTo(this.model, "change:tooltip", this.create_tooltip);
150-
this.model.on_some_change(['stroke', 'opacities', 'fill', 'stroke_width'], this.apply_styles, this);
151+
this.model.on_some_change(['stroke', 'fill', 'stroke_width'], this.apply_styles, this);
151152
this.listenTo(this.model, "change:selected", this.update_selected);
152153
this.listenTo(this.model, "change:interactions", this.process_interactions);
153154
this.listenTo(this.parent, "bg_clicked", () => {
@@ -686,25 +687,30 @@ export class Bars extends Mark {
686687
//if y is 1-d, each bar should be of 1 color.
687688
//if y is multi-dimensional, the corresponding values should be of
688689
//the same color.
690+
const stroke = this.model.get("stroke");
689691
if (this.model.mark_data.length > 0) {
690692
if (!(this.model.is_y_2d)) {
691693
this.d3el.selectAll(".bar")
692694
.style("fill", this.get_mark_color.bind(this))
695+
.style("stroke", stroke ? stroke : this.get_mark_color.bind(this))
693696
.style("opacity", this.get_mark_opacity.bind(this));
694697
} else {
695698
this.d3el.selectAll(".bargroup")
696699
.selectAll(".bar")
697700
.style("fill", this.get_mark_color.bind(this))
701+
.style("stroke", stroke ? stroke : this.get_mark_color.bind(this))
698702
.style("opacity", this.get_mark_opacity.bind(this));
699703
}
700704
}
701705
//legend color update
702706
if (this.legend_el) {
703707
this.legend_el.selectAll(".legendrect")
704708
.style("fill", this.get_mark_color.bind(this))
709+
.style("stroke", stroke ? stroke : this.get_mark_color.bind(this))
705710
.style("opacity", this.get_mark_opacity.bind(this));
706711
this.legend_el.selectAll(".legendtext")
707712
.style("fill", this.get_mark_color.bind(this))
713+
.style("stroke", stroke ? stroke : this.get_mark_color.bind(this))
708714
.style("opacity", this.get_mark_opacity.bind(this));
709715
}
710716
}

js/src/BarsModel.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,22 @@ export class BarsModel extends markmodel.MarkModel {
163163
const color_mode = this.get("color_mode");
164164
const apply_color_to_groups = ((color_mode === "group") ||
165165
(color_mode === "auto" && !(this.is_y_2d)));
166+
const apply_color_to_group_element = ((color_mode === "element") ||
167+
(color_mode === "auto" && this.is_y_2d));
168+
166169
const opacity_mode = this.get("opacity_mode");
167170
const apply_opacity_to_groups = ((opacity_mode === "group") ||
168171
(opacity_mode === "auto" && !(this.is_y_2d)));
172+
const apply_opacity_to_group_element = ((opacity_mode === "element") ||
173+
(opacity_mode === "auto" && this.is_y_2d));
169174

175+
let element_idx = 0;
170176
this.mark_data.forEach(function(single_bar_d, bar_grp_index) {
171177
single_bar_d.values.forEach(function(bar_d, bar_index) {
172-
bar_d.color_index = (apply_color_to_groups) ? bar_grp_index : bar_index;
173-
bar_d.opacity_index = (apply_opacity_to_groups) ? bar_grp_index : bar_index;
178+
bar_d.color_index = apply_color_to_groups ? bar_grp_index : apply_color_to_group_element ? bar_index : element_idx;
179+
bar_d.opacity_index = apply_opacity_to_groups ? bar_grp_index : apply_opacity_to_group_element ? bar_index : element_idx;
180+
181+
element_idx++;
174182
});
175183
});
176184

0 commit comments

Comments
 (0)