def goChart(label, stack_or_group, values, ylabel=None, color=None): convertPDFDate(workingPDF, keyFields[0]) if ylabel is None: ylabel=values label=label if isinstance(label, (list, tuple)) else [label] if stacked: charts.append( Bar(workingPDF, label=CatAttr(columns=label, sort=False), stack=stack_or_group, color=color, values=values, legend=self.showLegend(), ylabel=ylabel)) else: charts.append( Bar(workingPDF, label=CatAttr(columns=label, sort=False), group=stack_or_group, color=color, values=values, legend=self.showLegend(), ylabel=ylabel))
def author_frequency_barplot(nb_top_ners=50, tf=True): if tf: output_file('../figures/tf_authors.html') ner_freqs = pickle.load(open('../workspace/tf.m', "rb")) else: output_file('../figures/df_authors.html') ner_freqs = pickle.load(open('../workspace/df.m', "rb")) top_ners = [w for w, _ in ner_freqs.most_common(nb_top_ners)] top_freqs = [c for _, c in ner_freqs.most_common(nb_top_ners)] names = [] for name in top_ners: name = name.replace('*', '') if '(' in name: name = name.split('(')[0].strip() name = ' '.join([n.lower().capitalize() for n in name.split('_')]) name = ''.join([ c for c in unicodedata.normalize('NFKD', name) if not unicodedata.combining(c) ]) names.append(name) data = pd.DataFrame({'values': top_freqs[:25], 'labels': names[:25]}) bar1 = Bar(data, label=CatAttr(columns=['labels'], sort=False), values='values', title='Author Frequency (1-25)', width=800, height=400) xaxis = bar1.select(dict(type=Axis))[1] xaxis.major_label_standoff = 0 xaxis.major_label_orientation = np.pi / 2 xaxis.major_label_standoff = 6 xaxis.major_tick_out = 0 data = pd.DataFrame({'values': top_freqs[25:50], 'labels': names[25:50]}) bar2 = Bar(data, label=CatAttr(columns=['labels'], sort=False), values='values', title='Author Frequency (25-50)', width=800, height=400) xaxis = bar2.select(dict(type=Axis))[1] xaxis.major_label_standoff = 0 xaxis.major_label_orientation = np.pi / 2 xaxis.major_label_standoff = 6 xaxis.major_tick_out = 0 p = vplot(bar1, bar2) save(p)
def cashflow_chart(self): actual_list = [] actual_list1 = [] actual_list2 = [] for offset in range(0, 13): if offset: name = calendar.month_name[offset] invoice_chart_id = self.search([('month_no', '=', offset)]) actual_list.append( (name[:3], invoice_chart_id.awating_payment, 'Incoming')) actual_list1.append( (name[:3], invoice_chart_id.awating_out_payment, 'Outgoing')) full = actual_list + actual_list1 + actual_list2 acctual_amt_list = [] acctual_month_list = [] acctual_state_list = [] for ac_mo_sorted in order_months: for com_dict in full: month, amt, state = com_dict if month == ac_mo_sorted: if state == 'Incoming': acctual_amt_list.append(amt) acctual_month_list.append(month) acctual_state_list.append(state) if month == ac_mo_sorted: if state == 'Outgoing': acctual_amt_list.append(amt) acctual_month_list.append(month) acctual_state_list.append(state) col = [('green'), ('darkred')] data = pd.DataFrame({ 'Group': acctual_month_list, 'Year': acctual_state_list, 'Height': acctual_amt_list }) fig = Bar(data, title="CashFlow", values='Height', group='Year', color=col, legend='top_right', plot_width=600, plot_height=350, xlabel="Months", ylabel="Values", tools=TOOLS, logo=None, label=CatAttr(columns=['Group'], sort=False), tooltips=[('Month:', '@Group'), ('Value:', '@height')]) fig.legend.label_text_font_size = "8pt" fig.legend.label_height = -10 fig.legend.glyph_width = 10 fig.legend.glyph_height = 10 html = file_html(fig, CDN, "cashflow plot") template_id = self.env['html.template'].search( [('name', '=', 'Cashflow')], limit=1) if template_id: template_id.write({'text_file': html})
def get_bar_chart_markup(labels, values, chart_range=None): data = {"labels": labels, "values": values} bar = Bar(data, values="values", label=CatAttr(columns=["labels"], sort=False), legend=False, responsive=True) if chart_range: start, end = chart_range bar.y_range.start = start bar.y_range.end = end return get_chart_markup(bar)
def show_varimp(varimp, title): d2 = varimp plot2 = Bar(d2, values='percentage', plot_width=800, plot_height=800, label=CatAttr(columns='variable', sort=False), title=title, ylabel="Percentage Explained", color=Spectral4[1]) output_file('varimp.html') return plot2
def make_bar_plot(labels, values): data = {'labels': labels, 'values': values} bar = Bar(data, values='values', label=CatAttr(columns=['labels'], sort=False), legend=False, agg='mean', bar_width=0.6, plot_width=500, plot_height=350) bar.y_range = Range1d(0.0, 1.0) script, div = components(bar) return script, div
def plotG(data, ttl): fig = Bar(data, label=CatAttr(columns=['Group'], sort=False), values='Height', group='Spec', legend=True, plot_width=1000, plot_height=600, title=ttl, ylabel='MiB/s') fig.title.text_font_size = '18pt' # Show value in img fig.add_tools(HoverTool()) hover = fig.select(dict(type=HoverTool)) hover.tooltips = [('Spec', ' $x'), ('MiB/s', ' @height')] return fig
def hitrun_chart(value, value_label, filename): ''' Takes 3 string arguments: column name of attribute being pivoted with HIT_RUN_FLAG as "value", an axis label name as "value_label", and a filename for the final JS output as "filename" Outputs Bokeh plot in JS format for embedding ''' df = pd.pivot_table(crashes[crashes.HIT_RUN_FLAG == 'Yes'], values='HIT_RUN_FLAG', index=value, aggfunc='count') df = df.to_frame() hitrun_speed.reset_index(inplace=True) hover = HoverTool(tooltips=[ ("Total hit and runs", "@height"), ]) tools = [hover] a = Bar(df, label=CatAttr(columns=[value], sort=False), values='HIT_RUN_FLAG', plot_width=720, plot_height=720, color=color(columns='HIT_RUN_FLAG', palette=palette), tools=tools, legend='top_right', sizing_mode="scale_both") a.xaxis.axis_label = value_label a.yaxis.axis_label = 'Total number of hit and runs' #save file to JS script, div = components(a) foo = open(filename, 'w') foo.write(script) foo.close
def common_expense_global_summary(group_name): expense_data = group_query(group_name) expense_data = expense_data[['amount', 'domain']].groupby('domain', as_index=False).sum() expense_data = expense_data.sort_values( by='amount', ascending=False).reset_index(drop=True) fig = Bar(expense_data, label=CatAttr(columns=['domain'], sort=False), values='amount', agg='sum', color='domain', title='Expenses summary (common)', width=PLOT_WIDTH, height=PLOT_HEIGHT) fig.legend.border_line_alpha = 0 fig.legend.location = "bottom_left" fig.legend.background_fill_alpha = 0 return fig
class ChordBuilder(Builder): """ This is the Chord builder and it is in charge of plotting Chord graphs in an easy and intuitive way. Essentially, we provide a way to ingest the data, make the proper calculations and push the references into a source object. We additionally make calculations for the ranges. And finally add the needed glyphs (markers) taking the references from the source. """ default_attributes = {'color': ColorAttr(), 'marker': MarkerAttr(), 'stack': CatAttr()} dimensions = ['values'] values = Dimension('values') arcs_data = Instance(ColumnDataSource) text_data = Instance(ColumnDataSource) connection_data = Instance(ColumnDataSource) origin = String() destination = String() value = Any() square_matrix = Bool() label = Seq(Any()) matrix = Array(Array(Either(Float(), Int()))) def set_ranges(self): rng = 1.1 if not self.label else 1.8 self.x_range = Range1d(-rng, rng) self.y_range = Range1d(-rng, rng) def setup(self): # Process only if not a square_matrix if not self.square_matrix: source = self.values._data[self.origin] target = self.values._data[self.destination] union = source.append(target).unique() N = union.shape[0] m = pd.DataFrame(np.zeros((N, N)), columns=union, index=union) if not self.label: self.label = list(union) if self.value is None: for _, row in self.values._data.iterrows(): m[row[self.origin]][row[self.destination]] += 1 self.matrix = m.get_values() if self.value is not None: if isinstance(self.value, int) or isinstance(self.value, float): for _, row in self.values._data.iterrows(): m[row[self.origin]][row[self.destination]] = self.value self.matrix = m.get_values() elif isinstance(self.value, str): for _, row in self.values._data.iterrows(): m[row[self.origin]][row[self.destination]] = row[self.value] self.matrix = m.get_values().T else: # It's already a square matrix self.matrix = self._data.df.get_values() if self.label: assert len(self.label) == self.matrix.shape[0] def process_data(self): weights_of_areas = (self.matrix.sum(axis=0) + self.matrix.sum(axis=1)) - self.matrix.diagonal() areas_in_radians = (weights_of_areas / weights_of_areas.sum()) * (2 * pi) # We add a zero in the begging for the cumulative sum points = np.zeros((areas_in_radians.shape[0] + 1)) points[1:] = areas_in_radians points = points.cumsum() colors = [color_in_equal_space(area / areas_in_radians.shape[0]) for area in range(areas_in_radians.shape[0])] arcs_data = pd.DataFrame({ 'start_angle': points[:-1], 'end_angle': points[1:], 'line_color': colors }) self.arcs_data = ColumnDataSource(arcs_data) # Text if self.label: text_radius = 1.1 angles = (points[:-1]+points[1:])/2.0 text_positions = pd.DataFrame({ 'angles': angles, 'text_x': np.cos(angles) * text_radius, 'text_y': np.sin(angles) * text_radius, 'text': list(self.label) }) self.text_data = ColumnDataSource(text_positions) # Lines all_areas = [] for i in range(areas_in_radians.shape[0]): all_areas.append(Area(weights_of_areas[i], points[:-1][i], points[1:][i])) all_connections = [] for j, region1 in enumerate(self.matrix): # Get the connections origin region source = all_areas[j] color = colors[j] weight = weights_of_areas[j] for k, region2 in enumerate(region1): # Get the connection destination region target = all_areas[k] for _ in range(int(region2)): p1 = source.free_points.pop() p2 = target.free_points.pop() # Get both regions free points and create a connection with the data all_connections.append(p1 + p2 + [color, weight]) connections_df = pd.DataFrame(all_connections, dtype=str) connections_df.columns = ["start_x", "start_y", "end_x", "end_y", "colors", "weight"] connections_df["cx0"] = connections_df.start_x.astype("float64")/2 connections_df["cy0"] = connections_df.start_y.astype("float64")/2 connections_df["cx1"] = connections_df.end_x.astype("float64")/2 connections_df["cy1"] = connections_df.end_y.astype("float64")/2 connections_df.weight = (connections_df.weight.astype("float64")/connections_df.weight.astype("float64").sum()) * 3000 self.connection_data = ColumnDataSource(connections_df) def yield_renderers(self): """Use the marker glyphs to display the arcs and beziers. Takes reference points from data loaded at the ColumnDataSource. """ beziers = Bezier(x0='start_x', y0='start_y', x1='end_x', y1='end_y', cx0='cx0', cy0='cy0', cx1='cx1', cy1='cy1', line_alpha='weight', line_color='colors') yield GlyphRenderer(data_source=self.connection_data, glyph=beziers) arcs = Arc(x=0, y=0, radius=1, line_width=10, start_angle='start_angle', end_angle='end_angle', line_color='line_color') yield GlyphRenderer(data_source=self.arcs_data, glyph=arcs) if self.label: text_props = { "text_color": "#000000", "text_font_size": "8pt", "text_align": "left", "text_baseline": "middle" } labels = Text(x='text_x', y='text_y', text='text', angle='angles', **text_props ) yield GlyphRenderer(data_source=self.text_data, glyph=labels)
def createBokehChart(self): keyFields = self.getKeyFields() valueFields = self.getValueFields() clusterby = self.options.get("clusterby") stacked = self.options.get("charttype", "grouped") == "stacked" subplots = self.isSubplot() workingPDF = self.getWorkingPandasDataFrame().copy() def convertPDFDate(df, col): #Bokeh doesn't support datetime as index in Bar chart. Convert to String if len(keyFields) == 1: dtype = df[col].dtype.type if col in df else None if numpy.issubdtype(dtype, numpy.datetime64): dateFormat = self.options.get("dateFormat", None) try: df[col] = df[col].apply(lambda x: str(x).replace(':','-') if dateFormat is None else x.strftime(dateFormat)) except: self.exception("Error converting dateFormat {}".format(dateFormat)) df[col] = df[col].apply(lambda x: str(x).replace(':','-')) for index, row in workingPDF.iterrows(): for k in keyFields: if isinstance(row[k], str if sys.version >= '3' else basestring): row[k] = row[k].replace(':', '.') workingPDF.loc[index] = row charts=[] def goChart(label, stack_or_group, values, ylabel=None, color=None): convertPDFDate(workingPDF, keyFields[0]) if ylabel is None: ylabel=values label=label if isinstance(label, (list, tuple)) else [label] if stacked: charts.append( Bar(workingPDF, label=CatAttr(columns=label, sort=False), stack=stack_or_group, color=color, values=values, legend=self.showLegend(), ylabel=ylabel)) else: charts.append( Bar(workingPDF, label=CatAttr(columns=label, sort=False), group=stack_or_group, color=color, values=values, legend=self.showLegend(), ylabel=ylabel)) if clusterby is not None and (subplots or len(valueFields)<=1): subplots = subplots if len(valueFields)==1 or subplots else False if subplots: for j, valueField in enumerate(valueFields): pivot = workingPDF.pivot( index=keyFields[0], columns=clusterby, values=valueField ) for i,col in enumerate(pivot.columns[:10]): #max 10 data = pd.DataFrame({'values':pivot[col].values, 'names': pivot.index.values}) convertPDFDate(data, 'names') if subplots: charts.append( Bar(data, label=CatAttr(columns=['names'], sort=False), color = Colors.hexRGB( 1.*i/2 ), values='values', ylabel=valueField, legend=False, title="{0} = {1}".format(clusterby, pivot.columns[i]) ) ) else: goChart( keyFields[0], clusterby, valueFields[0]) else: if subplots: for i,valueField in enumerate(valueFields): goChart( keyFields[0], None, valueField, color=Colors.hexRGB( 1.*i/2 )) else: if len(valueFields) > 1: series = '_'.join(valueFields) values = blend(*valueFields, name=series.replace('_', ','), labels_name=series) else: series = False values = valueFields[0] goChart(keyFields, series, values, ylabel=','.join(valueFields)) if clusterby is not None: self.addMessage("Warning: 'Cluster By' ignored when grouped option with multiple Value Fields is selected") return charts
for index in singleDiseaseList: print singleDiseaseList[count] + " : " + str(diseaseCounter[count]) count += 1 elif (userFlag == '5'): if (dataOptions == 2): bubbleSortA(diseaseCounter, singleDiseaseList) ascendingData = { 'Disease Name': singleDiseaseList, '# of Occurances': diseaseCounter } asc = Bar(ascendingData, values='# of Occurances', label=CatAttr(columns=['Disease Name'], sort=False), title='U.S. Chronic Diseases(2007-2013)', color=userColor) output_file("bar2.html") show(asc) elif (dataOptions == 3): bubbleSortD(diseaseCounter, singleDiseaseList) descendingData = { 'Disease Name': singleDiseaseList, '# of Occurances': diseaseCounter } des = Bar(descendingData, values='# of Occurances', label=CatAttr(columns=['Disease Name'], sort=False), title='U.S. Chronic Diseases(2007-2013)', color=userColor)
y = [] for col in columns: rdf = df[[col, 'Preis(chf)']].dropna().apply(pd.to_numeric) length = len(rdf[(rdf[col] == 1)]) x.append(col.split("_")[1]) y.append(rdf[(rdf[col] == 1)]['Preis(chf)'].mean()) dict = {'values': y, 'names': x} df = pd.DataFrame(dict) df = df.sort_values('values') print(df) output_file("lines.html") # create a new plot with a title and axis labels #p = figure(title=selector + "-Preis Diagramm", x_axis_label=selector, y_axis_label='Preis(chf)', width=1200) from bokeh.charts.attributes import CatAttr p = Bar(df, label=CatAttr(columns=['names'], sort=False), values='values', width=1200, height=700) # add a line renderer with legend and line thickness #p.line(x_test[column],p_list, legend="Regression", line_width=2, line_color="red") # show the results show(p)
frequencies[keys] += 1 #Sort counted fields in descending order import operator sorted_frequencies = sorted(frequencies.items(), key=operator.itemgetter(1), reverse=True) #Output as text file #============================================================================== # f = open('sortedfrequencies.txt','w') # for t in sorted_frequencies: # line = ' ' . join(str(x) for x in t) # f.write(line + '\n') # f.close() #============================================================================== #Separate data keys, values = zip(*sorted_frequencies) df = {"Fields": keys, "values": values} #Output frequency bar chart from bokeh.charts import Bar, output_file, show from bokeh.charts.attributes import CatAttr p = Bar(df, values="values", label=CatAttr(columns=['Fields'], sort=False), title="Attack Pattern Field Frequency", legend=False) show(p)
def map_api(): conn = psycopg2.connect('dbname=taxi user=postgres') curs = conn.cursor() r = redis.StrictRedis() if request.method == 'GET': block_id = request.args.get('block', 514) cached = r.get(block_id) if cached: return jsonify(eval(cached)) else: curs.execute( "select latitude + 1/400, longitude + 1/400 from blocks where block_id = %s" % block_id) origin = list(curs.fetchone()) curs.execute(""" select latitude, longitude, name, neighborhood, sum(trips) * 1.0 / 181, sum(fares) / sum(trips), sum(length) / sum(trips) / 60 from trips a join blocks b ON dropoff_block = b.block_id join pois c on b.block_id = c.block_id where pickup_block = %s and year = 2015 group by 1,2,3,4 order by 5 desc limit 10 """ % block_id) results = curs.fetchall() destinations = [[x[0], x[1]] for x in results] names = [{ "name": str("%s, %s" % (x[2], x[3])), "trips": "%.1f" % x[4], "avg_fare": "$%.2f" % x[5], "avg_time": "%.1f mins" % x[6] } for x in results] paths = get_path(origin, destinations) destinations = [x[-1] for x in paths] averages = [ 474.889564336372847, 5998.46586211914, 792.464691318635 ] curs.execute( "select sum(trips) * 1.0 / 181, sum(fares) / sum(trips), sum(tips) / sum(trips) from trips_by_month where block_id = %s and date >= '2015-01-01'" % block_id) trips, fares, tips = map(lambda x: float(x), curs.fetchone()) perc = trips / averages[0] * 100 color = rg_gradient(0, 200, perc) info = """This block had on average <b>%.1f</b> trips per day in the first half of 2015. This is <font color="%s"><b >%.0f%%</b></font> more than the average block. <br><br> The average fare from this block is $%.2f with a tip of $%.2f""" % ( trips, color, perc, fares, tips) curs.execute(""" select cast(hour as varchar) as hour, trips * 1.0 / sum(trips) over() percentage from ( select * from (select hour, trips from trips_by_hour where block_id = %s and hour > 5 order by 1) a union all select * from (select hour, trips from trips_by_hour where block_id = %s and hour <= 5 order by 1) b) a """ % (block_id, block_id)) output = curs.fetchall() conn.commit() df = pd.DataFrame(output, columns=['Hour', 'Percentage']) df['Percentage'] = df['Percentage'].astype(float) bar = Bar(df, label=CatAttr(columns=['Hour'], sort=False), values='Percentage', title=None, width=500, legend=None, height=300, color='#375a7f') bk = {} bar = chart_theme(bar) bar.yaxis.axis_label = 'Percentage of Trips' bk['bar'] = "\n".join(reversed(components(bar))) curs.execute( "select date, trips from trips_by_month where block_id = %s order by 1" % block_id) output = curs.fetchall() line_dates = np.array([x[0] for x in output]) line_trips = np.array([x[1] / 1000 for x in output]) p = figure(width=500, height=300, x_axis_type="datetime") p.scatter(line_dates, line_trips, color='#375a7f') p.line(line_dates, savitzky_golay(line_trips, 11, 3), color='#bbbbbb', line_width=3) p = chart_theme(p) p.yaxis.axis_label = 'Number of trips (k)' bk['line'] = "\n".join(reversed(components(p))) results = dict(origin=origin, paths=paths, destinations=destinations, names=names, info=info, bk=bk) r.set(block_id, results) return jsonify(results)
def get_line_chart_markup(labels, values) -> Markup: data = {"labels": labels, "values": values} line = Line(data, values="values", label=CatAttr(columns=["labels"], sort=False)) return get_chart_markup(line)
def plot_lcoe(top): # all this can probably be done smarter with a Pandas DataFrame?! Any takers? aep = top.fin_a.net_aep fcr = top.fin_a.fixed_charge_rate turbine_lcoe = OrderedDict( Rotor=( fcr / aep * top.tcc_a.tcc.blade_cost * top.tcc_a.tcc.blade_number + fcr / aep * top.tcc_a.tcc.hub_system_cost) * top.turbine_number, Tower=fcr / aep * top.tcc_a.tcc.tower_cost * top.turbine_number, Nacelle=fcr / aep * top.tcc_a.tcc.nacelle_cost * top.turbine_number) infra_lcoe = OrderedDict( Assembly=fcr / aep * top.bos_breakdown.assembly_and_installation_costs, Development=fcr / aep * top.bos_breakdown.development_costs, Electrical=fcr / aep * top.bos_breakdown.electrical_costs, Substructure=fcr / aep * top.bos_breakdown.foundation_and_substructure_costs, Other=fcr / aep * top.bos_breakdown.foundation_and_substructure_costs, Preparation=fcr / aep * top.bos_breakdown.preparation_and_staging_costs, Soft=fcr / aep * top.bos_breakdown.soft_costs, Transportation=fcr / aep * top.bos_breakdown.transportation_costs) opex_lcoe = OrderedDict(Opex=top.opex_a.avg_annual_opex / aep) turbine_sum = np.sum(turbine_lcoe.values()) infra_sum = np.sum(infra_lcoe.values()) opex_sum = np.sum(opex_lcoe.values()) total_lcoe = np.array( [turbine_sum, infra_sum, opex_sum]) # array containing Turbine, BOS, and OPEX lcoe costs lcoe = total_lcoe.sum() total_lcoe = OrderedDict(Total=lcoe) everything_lcoe = turbine_lcoe everything_lcoe.update(infra_lcoe) everything_lcoe.update(opex_lcoe) cumSum = 0 invisibleBlock = OrderedDict() for key in everything_lcoe.keys(): invisibleBlock[key] = cumSum cumSum += everything_lcoe[key] everything_lcoe.update(total_lcoe) invisibleBlock['Total'] = 0 Combined = invisibleBlock.values() colors = ['white' for i in range(len(Combined))] next_color = palette.next() for i in range(3): colors.append(next_color) next_color = palette.next() for i in range(8): colors.append(next_color) colors.append(palette.next()) colors.append('black') myGroup = [] for x in range(2): for i in range(3): myGroup.append('turbine') for i in range(8): myGroup.append('infrastructure') myGroup.append('opex') myGroup.append('total') for stuff in everything_lcoe.values(): Combined.append(stuff) myKeys = OrderedDict(turbine=turbine_lcoe.keys(), infra=infra_lcoe.keys(), myOpex=opex_lcoe.keys()) myNames = myKeys['turbine'] for stuff in list(myKeys['turbine']): myNames.append(stuff) myStack = [] for i in range(13): myStack.append(1) for i in range(13): myStack.append(2) myDict = dict(Amount=Combined, Group=myGroup, Names=myNames, stack=myStack, color=colors) myDF = df(data=myDict) # print myDF myBar = Bar( myDF, values='Amount', label=CatAttr(columns=['Names'], sort=False), stack="stack", toolbar_location="above", color="color", ygrid=False, legend=None, title='LCOE Costs Breakdown', ylabel="LCOE ($/kWh)", xlabel="Component", tools="crosshair,pan,wheel_zoom,box_zoom,reset,hover,previewsave", ) hover = myBar.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ("Component", "@Names"), # ("Group", "@Group"), # maybe one day bokeh will fix this and it will work. It should show "turbine, infra, or opex" ]) return myBar
comparison_df.set_value(index=1, col="Number of Votes", value=disagree_votes) return comparison_df, comparison_series comparison_df, comparison_series = compare_politicians("Tim Kaine", "Mark Warner", "senate") hover = HoverTool( tooltips=[ ("Number of Votes", "@height") ]) TOOLS = [SaveTool(), hover] # plot = Bar(comparison_df, values = "Number of Votes", label=CatAttr(columns=['Votes'], sort = False), group='Votes', legend='top_right', color=ColorAttr(columns=['Votes']), tools="resize,hover,save") barplot = Bar(comparison_df, values="Number of Votes", label=CatAttr(columns=['Votes'], sort=False), group='Votes', legend='top_right', color='Votes', tools=TOOLS, ylabel="Number of Votes") for r in barplot.renderers: try: r.glyph.width = 1.15 except AttributeError: pass # show(barplot) script_barplot, div_barplot = components(barplot) pie_chart = Donut(comparison_series, tools="save") # show(pie_chart) script_piechart, div_piechart = components(barplot)