Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 69bd30d

Browse filesBrowse files
committed
reworked bullet charts with bar traces
1 parent 8ba62a2 commit 69bd30d
Copy full SHA for 69bd30d

File tree

Expand file treeCollapse file tree

2 files changed

+392
-396
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+392
-396
lines changed

‎plotly/figure_factory/_bullet.py

Copy file name to clipboardExpand all lines: plotly/figure_factory/_bullet.py
+89-104Lines changed: 89 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,33 @@
1010

1111
pd = optional_imports.get_module('pandas')
1212

13-
SUBPLOT_SPACING = 0.015
1413
VALID_KEYS = ['title', 'subtitle', 'ranges', 'measures', 'markers']
1514

1615

17-
# add shapes
18-
def rectangle(color, x0, x1, y0, y1, xref, yref, layer):
19-
return {
20-
'fillcolor': color,
21-
'line': {'width': 0},
22-
'opacity': 1,
23-
'type': 'rect',
24-
'x0': x0,
25-
'x1': x1,
26-
'xref': xref,
27-
'y0': y0,
28-
'y1': y1,
29-
'yref': yref,
30-
'layer': layer
31-
}
32-
33-
3416
def _bullet(df, as_rows, marker_size, marker_symbol, range_colors,
35-
measure_colors):
17+
measure_colors, subplot_spacing):
3618
num_of_lanes = len(df)
3719
num_of_rows = num_of_lanes if as_rows else 1
3820
num_of_cols = 1 if as_rows else num_of_lanes
21+
if not subplot_spacing:
22+
subplot_spacing = 1./num_of_lanes
3923
fig = plotly.tools.make_subplots(
4024
num_of_rows, num_of_cols, print_grid=False,
41-
horizontal_spacing=SUBPLOT_SPACING,
42-
vertical_spacing=SUBPLOT_SPACING
25+
horizontal_spacing=subplot_spacing,
26+
vertical_spacing=subplot_spacing
4327
)
4428

4529
# layout
4630
fig['layout'].update(
4731
dict(shapes=[]),
4832
showlegend=False,
49-
annotations=[],
33+
barmode='stack',
5034
margin=dict(l=120 if as_rows else 80),
5135
)
5236

5337
if as_rows:
54-
length_axis = 'xaxis'
5538
width_axis = 'yaxis'
39+
length_axis = 'xaxis'
5640
else:
5741
width_axis = 'xaxis'
5842
length_axis = 'yaxis'
@@ -67,105 +51,102 @@ def _bullet(df, as_rows, marker_size, marker_symbol, range_colors,
6751
fig['layout'][key]['showticklabels'] = False
6852
fig['layout'][key]['range'] = [0, 1]
6953

54+
# narrow domain if 1 bar
55+
if num_of_lanes <= 1:
56+
fig['layout'][width_axis + '1']['domain'] = [0.4, 0.6]
57+
7058
# marker symbol size
7159
if not marker_size:
72-
if num_of_lanes <= 3:
60+
if num_of_lanes <= 4:
7361
marker_size = 18
7462
else:
75-
marker_size = 12
76-
for idx in range(num_of_lanes):
77-
# marker
78-
x = df.iloc[idx]['markers'] if as_rows else [0.5]
79-
y = [0.5] if as_rows else df.iloc[idx]['markers']
80-
fig['data'].append(
81-
go.Scatter(
63+
marker_size = 8
64+
65+
if not range_colors:
66+
range_colors = ['rgb(200, 200, 200)', 'rgb(245, 245, 245)']
67+
if not measure_colors:
68+
measure_colors = ['rgb(31, 119, 180)', 'rgb(176, 196, 221)']
69+
70+
for row in range(num_of_lanes):
71+
# ranges bars
72+
for idx in range(len(df.iloc[row]['ranges'])):
73+
inter_colors = colors.n_colors(
74+
range_colors[0], range_colors[1],
75+
len(df.iloc[row]['ranges']), 'rgb'
76+
)
77+
x = [sorted(df.iloc[row]['ranges'])[-1 - idx]] if as_rows else [0]
78+
y = [0] if as_rows else [sorted(df.iloc[row]['ranges'])[-1 - idx]]
79+
bar = go.Bar(
8280
x=x,
8381
y=y,
8482
marker=dict(
85-
size=marker_size,
86-
color='rgb(0, 0, 0)',
87-
symbol=marker_symbol
83+
color=inter_colors[-1 - idx]
8884
),
89-
xaxis='x{}'.format(idx + 1),
90-
yaxis='y{}'.format(idx + 1)
85+
name='ranges',
86+
hoverinfo='x' if as_rows else 'y',
87+
orientation='h' if as_rows else 'v',
88+
width=2,
89+
base=0,
90+
xaxis='x{}'.format(row + 1),
91+
yaxis='y{}'.format(row + 1)
9192
)
92-
)
93+
fig['data'].append(bar)
9394

94-
# ranges
95-
y0_ranges = 0.35
96-
y1_ranges = 0.65
97-
if not range_colors:
98-
range_colors = ['rgb(200, 200, 200)', 'rgb(245, 245, 245)']
99-
ranges_len = len(df.iloc[idx]['ranges'])
100-
if ranges_len <= 1:
101-
inter_colors = [range_colors[0]]
102-
else:
95+
# measures bars
96+
for idx in range(len(df.iloc[row]['measures'])):
10397
inter_colors = colors.n_colors(
104-
range_colors[0], range_colors[1], ranges_len, 'rgb'
105-
)
106-
for range_idx in range(ranges_len):
107-
color = inter_colors[range_idx]
108-
if range_idx == 0:
109-
start_range = 0
110-
else:
111-
start_range = df.iloc[idx]['ranges'][range_idx - 1]
112-
end_range = df.iloc[idx]['ranges'][range_idx]
113-
114-
x0 = start_range if as_rows else y0_ranges
115-
x1 = end_range if as_rows else y1_ranges
116-
y0 = y0_ranges if as_rows else start_range
117-
y1 = y1_ranges if as_rows else end_range
118-
fig['layout']['shapes'].append(
119-
rectangle(
120-
color, x0, x1, y0, y1,
121-
'x{}'.format(idx + 1),
122-
'y{}'.format(idx + 1),
123-
'below'
124-
)
98+
measure_colors[0], measure_colors[1],
99+
len(df.iloc[row]['measures']), 'rgb'
125100
)
126-
127-
# measures
128-
y0_measures = 0.45
129-
y1_measures = 0.55
130-
if not measure_colors:
131-
measure_colors = ['rgb(31, 119, 180)', 'rgb(176, 196, 221)']
132-
measures_len = len(df.iloc[idx]['measures'])
133-
if measures_len <= 1:
134-
inter_colors = [measure_colors[0]]
135-
else:
136-
inter_colors = colors.n_colors(
137-
measure_colors[0], measure_colors[1], measures_len, 'rgb'
101+
x = ([sorted(df.iloc[row]['measures'])[-1 - idx]] if as_rows
102+
else [0.5])
103+
y = ([0.5] if as_rows
104+
else [sorted(df.iloc[row]['measures'])[-1 - idx]])
105+
bar = go.Bar(
106+
x=x,
107+
y=y,
108+
marker=dict(
109+
color=inter_colors[-1 - idx]
110+
),
111+
name='measures',
112+
hoverinfo='x' if as_rows else 'y',
113+
orientation='h' if as_rows else 'v',
114+
width=0.4,
115+
base=0,
116+
xaxis='x{}'.format(row + 1),
117+
yaxis='y{}'.format(row + 1)
138118
)
139-
for range_idx in range(measures_len):
140-
color = inter_colors[range_idx]
141-
if range_idx == 0:
142-
start_range = 0
143-
else:
144-
start_range = df.iloc[idx]['measures'][range_idx - 1]
145-
end_range = df.iloc[idx]['measures'][range_idx]
119+
fig['data'].append(bar)
146120

147-
x0 = start_range if as_rows else y0_measures
148-
x1 = end_range if as_rows else y1_measures
149-
y0 = y0_measures if as_rows else start_range
150-
y1 = y1_measures if as_rows else end_range
151-
fig['layout']['shapes'].append(
152-
rectangle(
153-
color, x0, x1, y0, y1,
154-
'x{}'.format(idx + 1),
155-
'y{}'.format(idx + 1),
156-
'below'
157-
)
158-
)
121+
# markers
122+
x = df.iloc[row]['markers'] if as_rows else [0.5]
123+
y = [0.5] if as_rows else df.iloc[row]['markers']
124+
markers = go.Scatter(
125+
x=x,
126+
y=y,
127+
marker=dict(
128+
color='rgb(0, 0, 0)',
129+
symbol=marker_symbol,
130+
size=marker_size
131+
),
132+
name='markers',
133+
hoverinfo='x' if as_rows else 'y',
134+
xaxis='x{}'.format(row + 1),
135+
yaxis='y{}'.format(row + 1)
136+
)
137+
fig['data'].append(markers)
159138

160139
# labels
161-
title = df.iloc[idx]['title']
140+
title = df.iloc[row]['title']
162141
if 'subtitle' in df:
163-
subtitle = '<br>{}'.format(df.iloc[idx]['subtitle'])
142+
subtitle = '<br>{}'.format(df.iloc[row]['subtitle'])
164143
else:
165144
subtitle = ''
166145
label = '<b>{}</b>'.format(title) + subtitle
167146
annot = utils.annotation_dict_for_label(
168-
label, num_of_lanes - idx, num_of_lanes, SUBPLOT_SPACING,
147+
label,
148+
(num_of_lanes - row if as_rows else row + 1),
149+
num_of_lanes, subplot_spacing,
169150
'row' if as_rows else 'col',
170151
True if as_rows else False,
171152
False
@@ -177,8 +158,8 @@ def _bullet(df, as_rows, marker_size, marker_symbol, range_colors,
177158

178159
def create_bullet(df, as_rows=True, marker_size=16,
179160
marker_symbol='diamond-tall', range_colors=None,
180-
measure_colors=None, title='Bullet Chart', height=600,
181-
width=1000):
161+
measure_colors=None, subplot_spacing=None,
162+
title='Bullet Chart', height=600, width=1000):
182163
"""
183164
Returns figure for bullet chart.
184165
@@ -198,6 +179,9 @@ def create_bullet(df, as_rows=True, marker_size=16,
198179
:param (list) measure_colors: a list of two colors which is used to color
199180
the thin quantitative bars in the bullet chart.
200181
Default=['rgb(31, 119, 180)', 'rgb(176, 196, 221)']
182+
:param (float) subplot_spacing: set the distance between each bar chart.
183+
If not specified an automatic spacing is assigned based on the number
184+
of bars to be plotted.
201185
:param (str) title: title of the bullet chart.
202186
:param (float) height: height of the chart.
203187
:param (float) width width of the chart.
@@ -260,7 +244,8 @@ def create_bullet(df, as_rows=True, marker_size=16,
260244
'rgb')[0]
261245

262246
fig = _bullet(
263-
df, as_rows, marker_size, marker_symbol, range_colors, measure_colors
247+
df, as_rows, marker_size, marker_symbol, range_colors, measure_colors,
248+
subplot_spacing
264249
)
265250

266251
fig['layout'].update(

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.