def plot_circle_density(nodes, degrees, plot_width=800, plot_height=800): print("Plotting circle density graph") TOOLS="hover,pan,wheel_zoom,box_zoom,reset,click,previewsave" plt.figure(plot_width=plot_width, plot_height=plot_height, tools=TOOLS) theta = np.random.uniform(0, 2*np.pi, size=len(nodes)) max_d, min_d = np.max(degrees), np.min(degrees) scale = 1.0/np.log(degrees) - 1.0/np.log(max_d) xs = np.cos(theta)*scale ys = np.sin(theta)*scale source_dict = dict( xs = xs, ys = ys, degrees = degrees, nodes = nodes, alphas = np.log(degrees)/np.log(max(degrees)), ) source = ColumnDataSource(source_dict) plt.hold(True) plt.circle('xs', 'ys', source=source, radius=0.0025, fill_alpha='alphas', x_axis_type=None, y_axis_type=None, title="Density Distribution of Degrees") plt.text([max(xs), max(xs)], [.95*max(ys), .85*max(ys)], ["distance from center = 1 / log(deg)", "angle = random"], angle=0, text_baseline="bottom", text_align="right") hover = [t for t in plt.curplot().tools if isinstance(t, HoverTool)][0] hover.tooltips = OrderedDict([ ('node', '@nodes'), ('degree', '@degrees') ]) plt.hold(False) return plt.curplot()
def make_box_violin_plot_2(data, maxwidth=0.9): """ data: dict[Str -> List[Number]] maxwidth: float Maximum width of tornado plot within each factor/facet Returns the plot object """ df = pd.DataFrame(columns=["group", "centers", "width", "height", "texts"]) bar_height = 50 bins = [0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6] # Compute histograms, while keeping track of max Y values and max counts for i, (group, vals) in enumerate(data.iteritems()): hist, edges = np.histogram(vals, bins) df = df.append(pd.DataFrame(dict( group = group, centers = np.arange(len(hist))*bar_height, width = np.log10(hist), height = np.ones(hist.shape)*bar_height, texts = map(str,hist), ))) df.replace(-np.inf, 0) # Normalize the widths df["width"] *= (maxwidth / df["width"].max()) hold() width, height = 800, 800 figure(plot_width=width, plot_height=height, title="Degree Distribution", tools="previewsave", x_axis_type=None, y_axis_type=None, x_range=[-420, 420], y_range=[-420, 420], x_axis_label="Number of nodes (log)", y_label="distribution of degree", min_border=0, outline_line_color=None, background_fill="#f0e1d2", border_fill="#f0e1d2") size = len(df) rect(np.zeros(size), df["centers"], height=[50 for i in range(size)], width=df["width"]*width * .8) text(np.zeros(size), df["centers"], text=df["texts"], angle=np.zeros(size), text_color= ["#000000"] + ["#FFFFFF" for i in xrange(size-1)], text_align="center", text_baseline="middle") text(np.ones(size+1) * -width/2, [(idx-0.75)*bar_height for idx in range(size+1)], text=map(str, map(int, bins)), angle=0) show()
def drawPlot(shapeFilename, zipBorough, zipMaxAgency): # Read the ShapeFile dat = shapefile.Reader(shapeFilename) # Creates a dictionary for zip: {lat_list: [], lng_list: []}. zipCodes = [] hoverZip = [] hoverAgency = [] hoverComplaints = [] polygons = {'lat_list': [], 'lng_list': [], 'centerLat_list': [], 'centerLon_list': []} record_index = 0 for r in dat.iterRecords(): currentZip = r[0] # Keeps only zip codes in NY area. if currentZip in zipMaxAgency: # was in zipBorough: # zipCodes.append(currentZip) # moving this line into the parts loop # Gets shape for this zip. shape = dat.shapeRecord(record_index).shape for part in range(len(shape.parts)): zipCodes.append(currentZip) hoverZip.append(currentZip) hoverAgency.append(zipMaxAgency[currentZip][0]) hoverComplaints.append(zipMaxAgency[currentZip][1]) start = shape.parts[part] if part == len(shape.parts) - 1: end = len(shape.points) else: end = shape.parts[part + 1] points = shape.points[start : end] # Breaks into lists for lat/lng. lngs = [p[0] for p in points] lats = [p[1] for p in points] # Calculate centers center_lngs = min(lngs) + (max(lngs) - min(lngs))/2 center_lats = min(lats) + (max(lats) - min(lats))/2 # Store centroids for current part shape polygons['centerLat_list'].append(center_lats) polygons['centerLon_list'].append(center_lngs) # Stores lat/lng for current zip shape. polygons['lng_list'].append(lngs) polygons['lat_list'].append(lats) record_index += 1 # Palette ##d9d9d9 brewer11 = ['#8dd3c7', '#ffffb3', '#bebada','#fb8072','#80b1d3','#fdb462','#b3de69','#fccde5','#d9d9d9','#bc80bd','#ccebc5'] #brewer11 = ['#a6cee3', '#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99'] #agencies = sorted(list({zipMaxAgency[zipCode] for zipCode in zipMaxAgency})) biggestComplaints = {} for zz, aa in zipMaxAgency.iteritems(): if aa[0] in biggestComplaints: biggestComplaints[aa[0]] += 1 else: biggestComplaints[aa[0]] = 1 # sorting agencies by number of zip codes (to try to get better colors) agencies = list(biggestComplaints.iteritems()) agencies = sorted(agencies, key = lambda x: x[1], reverse = True) agencies = [agency[0] for agency in agencies] # Assign colors to agencies agencyColor = {agencies[i] : brewer11[i] for i in range(len(brewer11))} polygons['colors'] = [agencyColor[zipMaxAgency[zipCode][0]] for zipCode in zipCodes] # Prepare hover #source = bk.ColumnDataSource(data=dict(hoverAgency=hoverAgency, hoverZip=hoverZip, hoverComplaintCount=hoverComplaintCount,)) source = bk.ColumnDataSource(data=dict(hoverZip = hoverZip, hoverAgency = hoverAgency, hoverComplaints = hoverComplaints),) # Creates the Plot bk.output_file("problem1.html") bk.hold() TOOLS="pan,wheel_zoom,box_zoom,reset,previewsave,hover" fig = bk.figure(title="311 Complaints by Zip Code", \ tools=TOOLS, plot_width=800, plot_height=650) # Creates the polygons. bk.patches(polygons['lng_list'], polygons['lat_list'], fill_color=polygons['colors'], line_color="gray", source = source) # RP: add hover hover = bk.curplot().select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ("Zip", "@hoverZip"), ("Agency", "@hoverAgency"), ("Number of complaints", "@hoverComplaints"), ]) ### Zip codes as text on polygons #for i in range(len(polygons['centerLat_list'])): # y = polygons['centerLat_list'][i] # x = polygons['centerLon_list'][i] # zipCode = zipCodes[i] # bk.text([x], [y], text=zipCode, angle=0, text_font_size="8pt", text_align="center", text_baseline="middle") fonts = ["Comic sans MS", "Papyrus", "Curlz", "Impact", "Zapf dingbats", "Comic sans MS", "Papyrus", "Curlz", "Impact", "Zapf Dingbats", "Comic sans MS"] ### Legend x = -73.66 y = 40.50 #x = -74.25 #y = 40.9 for agency, color in agencyColor.iteritems(): #print "Color: ", a #print "x:", x #print "y:", y bk.rect([x], [y], color = color, width=0.03, height=0.015) bk.text([x], [y], text = agency, angle=0, text_font_size="7pt", text_align="center", text_baseline="middle") y = y + 0.015 #bokeh.embed.components(fig, bokeh.resources.CDN) bk.show()
def drawPlot(shapeFilename, zipBorough, grids, centers, gridLines): # Read the ShapeFile dat = shapefile.Reader(shapeFilename) # Creates a dictionary for zip: {lat_list: [], lng_list: []}. zipCodes = [] polygons = {'lat_list': [], 'lng_list': [], 'centerLat_list': [], 'centerLon_list': []} record_index = 0 for r in dat.iterRecords(): currentZip = r[0] # Keeps only zip codes in NY area. if currentZip in zipBorough: # was in zipBorough: # Gets shape for this zip. shape = dat.shapeRecord(record_index).shape for part in range(len(shape.parts)): zipCodes.append(currentZip) start = shape.parts[part] if part == len(shape.parts) - 1: end = len(shape.points) else: end = shape.parts[part + 1] points = shape.points[start : end] # Breaks into lists for lat/lng. lngs = [p[0] for p in points] lats = [p[1] for p in points] # Calculate centers center_lngs = min(lngs) + (max(lngs) - min(lngs))/2 center_lats = min(lats) + (max(lats) - min(lats))/2 # Store centroids for current part shape polygons['centerLat_list'].append(center_lats) polygons['centerLon_list'].append(center_lngs) # Stores lat/lng for current zip shape. polygons['lng_list'].append(lngs) polygons['lat_list'].append(lats) record_index += 1 # Creates the Plot bk.output_file("problem3.html") bk.hold() north = 40.915 east = -73.651 south = 40.496 west = -74.256 width = east - west height = north - south x_range = [west - 0.05 * width, east + 0.05 * width] y_range = [south - 0.05 * height, north + 0.05 * height] TOOLS="pan,wheel_zoom,box_zoom,reset,previewsave" fig = bk.figure(title="311 Complaints by Zip Code", \ tools=TOOLS, background_fill = "#f8f8f8", x_range = x_range, y_range = y_range) circleSizes = [item for sublist in grids['log_counts'] for item in sublist] # Creates the polygons cellWidth = gridLines['vLines'][1]-gridLines['vLines'][0] cellHeight = gridLines['hLines'][1] - gridLines['hLines'][0] bk.patches(polygons['lng_list'], polygons['lat_list'], fill_color="#fee8c8", line_color="gray") circleSizes = [0.009 * (size ** 3.7) for size in circleSizes] bk.scatter(centers['lon'], centers['lat'], size = circleSizes, alpha = 0.4, line_color = None, fill_color = 'red') bk.hold() #print type(centers['lon']) circleSizeArr = np.array(circleSizes) maxSize = np.max(circleSizeArr) circleSizeArr[circleSizeArr == 0] = 100 minSize = np.min(circleSizeArr) #print minSize, maxSize legendN = 5 legendCircles = list(np.linspace(minSize, maxSize, legendN)) legendCounts = [str(int(math.exp(((size/0.009) ** (1.0/3.7))))) + " complaints" for size in legendCircles] #print legendCircles fakeScatter = [0 for x in range(legendN)] fakeScatterX = [-74.23 for x in range(legendN)] fakeScatterXtext = [-74.23 + 0.05 for x in range(legendN)] #fakeScatterY = [40.8 + 0.028*y for y in range(legendN)] fakeScatterY = [40.8, 40.8 + 0.02, 40.8 + 0.036, 40.8 + 0.056,40.8 + 0.083] #print fakeScatterX, type(fakeScatterX) #print fakeScatterY, type(fakeScatterY) bk.scatter(fakeScatterX, fakeScatterY, size = legendCircles, fill_color = 'red', line_color = None, alpha = 0.4) bk.text(fakeScatterXtext[1:], fakeScatterY[1:], text = legendCounts[1:], angle = 0, text_align = "left", text_font_size = "7pt", text_baseline = 'middle') #for i in range(len(fakeScatter)): # bk.scatter([fakeScatter[i]], [fakeScatter[i]], size = [legendCircles[i]], legend = int(legendCircles[i]), color = 'red', fill_line = None, alpha = 0.4) # Disable background grid bk.grid().grid_line_color = None #print centers ### Legend #x = -74.25 #y = 40.8 #height = 0.003 #legend_box_y = y + 0.5 * height * len(legendColors) #bk.rect([x+0.032], [legend_box_y], width = 0.12, height = height*len(legendColors)*1.15, color = "#ffffff", line_color = "gray") ##x = -74.25 ##y = 40.9 #for color in legendColors: ## #print "Color: ", a ## #print "x:", x ## #print "y:", y ## # bk.rect([x], [y], color = color, width=0.03, height=height) # #bk.text([x], [y], text = agency, angle=0, text_font_size="7pt", text_align="center", text_baseline="middle") # y = y + height #legend_bottom_y = 40.797 #legend_top_y = legend_bottom_y + 0.92 * height * len(legendColors) #bk.text([-74.225], [legend_bottom_y], text = agency2, angle = 0, text_font_size = "7pt", text_align = "left") #bk.text([-74.225], [legend_top_y], text = agency1, angle = 0, text_font_size = "7pt", text_align = "left") #bokeh.embed.components(fig, bokeh.resources.CDN) bk.show()
def drawPlot(shapeFilename, zipBorough, zipMaxAgency): # Read the ShapeFile dat = shapefile.Reader(shapeFilename) # Creates a dictionary for zip: {lat_list: [], lng_list: []}. zipCodes = [] hoverZip = [] hoverAgency = [] hoverComplaints = [] polygons = { 'lat_list': [], 'lng_list': [], 'centerLat_list': [], 'centerLon_list': [] } record_index = 0 for r in dat.iterRecords(): currentZip = r[0] # Keeps only zip codes in NY area. if currentZip in zipMaxAgency: # was in zipBorough: # zipCodes.append(currentZip) # moving this line into the parts loop # Gets shape for this zip. shape = dat.shapeRecord(record_index).shape for part in range(len(shape.parts)): zipCodes.append(currentZip) hoverZip.append(currentZip) hoverAgency.append(zipMaxAgency[currentZip][0]) hoverComplaints.append(zipMaxAgency[currentZip][1]) start = shape.parts[part] if part == len(shape.parts) - 1: end = len(shape.points) else: end = shape.parts[part + 1] points = shape.points[start:end] # Breaks into lists for lat/lng. lngs = [p[0] for p in points] lats = [p[1] for p in points] # Calculate centers center_lngs = min(lngs) + (max(lngs) - min(lngs)) / 2 center_lats = min(lats) + (max(lats) - min(lats)) / 2 # Store centroids for current part shape polygons['centerLat_list'].append(center_lats) polygons['centerLon_list'].append(center_lngs) # Stores lat/lng for current zip shape. polygons['lng_list'].append(lngs) polygons['lat_list'].append(lats) record_index += 1 # Palette ##d9d9d9 brewer11 = [ '#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5' ] #brewer11 = ['#a6cee3', '#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99'] #agencies = sorted(list({zipMaxAgency[zipCode] for zipCode in zipMaxAgency})) biggestComplaints = {} for zz, aa in zipMaxAgency.iteritems(): if aa[0] in biggestComplaints: biggestComplaints[aa[0]] += 1 else: biggestComplaints[aa[0]] = 1 # sorting agencies by number of zip codes (to try to get better colors) agencies = list(biggestComplaints.iteritems()) agencies = sorted(agencies, key=lambda x: x[1], reverse=True) agencies = [agency[0] for agency in agencies] # Assign colors to agencies agencyColor = {agencies[i]: brewer11[i] for i in range(len(brewer11))} polygons['colors'] = [ agencyColor[zipMaxAgency[zipCode][0]] for zipCode in zipCodes ] # Prepare hover #source = bk.ColumnDataSource(data=dict(hoverAgency=hoverAgency, hoverZip=hoverZip, hoverComplaintCount=hoverComplaintCount,)) source = bk.ColumnDataSource(data=dict(hoverZip=hoverZip, hoverAgency=hoverAgency, hoverComplaints=hoverComplaints), ) # Creates the Plot bk.output_file("problem1.html") bk.hold() TOOLS = "pan,wheel_zoom,box_zoom,reset,previewsave,hover" fig = bk.figure(title="311 Complaints by Zip Code", \ tools=TOOLS, plot_width=800, plot_height=650) # Creates the polygons. bk.patches(polygons['lng_list'], polygons['lat_list'], fill_color=polygons['colors'], line_color="gray", source=source) # RP: add hover hover = bk.curplot().select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ("Zip", "@hoverZip"), ("Agency", "@hoverAgency"), ("Number of complaints", "@hoverComplaints"), ]) ### Zip codes as text on polygons #for i in range(len(polygons['centerLat_list'])): # y = polygons['centerLat_list'][i] # x = polygons['centerLon_list'][i] # zipCode = zipCodes[i] # bk.text([x], [y], text=zipCode, angle=0, text_font_size="8pt", text_align="center", text_baseline="middle") fonts = [ "Comic sans MS", "Papyrus", "Curlz", "Impact", "Zapf dingbats", "Comic sans MS", "Papyrus", "Curlz", "Impact", "Zapf Dingbats", "Comic sans MS" ] ### Legend x = -73.66 y = 40.50 #x = -74.25 #y = 40.9 for agency, color in agencyColor.iteritems(): #print "Color: ", a #print "x:", x #print "y:", y bk.rect([x], [y], color=color, width=0.03, height=0.015) bk.text([x], [y], text=agency, angle=0, text_font_size="7pt", text_align="center", text_baseline="middle") y = y + 0.015 #bokeh.embed.components(fig, bokeh.resources.CDN) bk.show()
def drawPlot(shapeFilename, zipBorough, grids, centers, gridLines): # Read the ShapeFile dat = shapefile.Reader(shapeFilename) # Creates a dictionary for zip: {lat_list: [], lng_list: []}. zipCodes = [] polygons = { 'lat_list': [], 'lng_list': [], 'centerLat_list': [], 'centerLon_list': [] } record_index = 0 for r in dat.iterRecords(): currentZip = r[0] # Keeps only zip codes in NY area. if currentZip in zipBorough: # was in zipBorough: # Gets shape for this zip. shape = dat.shapeRecord(record_index).shape for part in range(len(shape.parts)): zipCodes.append(currentZip) start = shape.parts[part] if part == len(shape.parts) - 1: end = len(shape.points) else: end = shape.parts[part + 1] points = shape.points[start:end] # Breaks into lists for lat/lng. lngs = [p[0] for p in points] lats = [p[1] for p in points] # Calculate centers center_lngs = min(lngs) + (max(lngs) - min(lngs)) / 2 center_lats = min(lats) + (max(lats) - min(lats)) / 2 # Store centroids for current part shape polygons['centerLat_list'].append(center_lats) polygons['centerLon_list'].append(center_lngs) # Stores lat/lng for current zip shape. polygons['lng_list'].append(lngs) polygons['lat_list'].append(lats) record_index += 1 # Creates the Plot bk.output_file("problem3.html") bk.hold() north = 40.915 east = -73.651 south = 40.496 west = -74.256 width = east - west height = north - south x_range = [west - 0.05 * width, east + 0.05 * width] y_range = [south - 0.05 * height, north + 0.05 * height] TOOLS = "pan,wheel_zoom,box_zoom,reset,previewsave" fig = bk.figure(title="311 Complaints by Zip Code", \ tools=TOOLS, background_fill = "#f8f8f8", x_range = x_range, y_range = y_range) circleSizes = [item for sublist in grids['log_counts'] for item in sublist] # Creates the polygons cellWidth = gridLines['vLines'][1] - gridLines['vLines'][0] cellHeight = gridLines['hLines'][1] - gridLines['hLines'][0] bk.patches(polygons['lng_list'], polygons['lat_list'], fill_color="#fee8c8", line_color="gray") circleSizes = [0.009 * (size**3.7) for size in circleSizes] bk.scatter(centers['lon'], centers['lat'], size=circleSizes, alpha=0.4, line_color=None, fill_color='red') bk.hold() #print type(centers['lon']) circleSizeArr = np.array(circleSizes) maxSize = np.max(circleSizeArr) circleSizeArr[circleSizeArr == 0] = 100 minSize = np.min(circleSizeArr) #print minSize, maxSize legendN = 5 legendCircles = list(np.linspace(minSize, maxSize, legendN)) legendCounts = [ str(int(math.exp(((size / 0.009)**(1.0 / 3.7))))) + " complaints" for size in legendCircles ] #print legendCircles fakeScatter = [0 for x in range(legendN)] fakeScatterX = [-74.23 for x in range(legendN)] fakeScatterXtext = [-74.23 + 0.05 for x in range(legendN)] #fakeScatterY = [40.8 + 0.028*y for y in range(legendN)] fakeScatterY = [ 40.8, 40.8 + 0.02, 40.8 + 0.036, 40.8 + 0.056, 40.8 + 0.083 ] #print fakeScatterX, type(fakeScatterX) #print fakeScatterY, type(fakeScatterY) bk.scatter(fakeScatterX, fakeScatterY, size=legendCircles, fill_color='red', line_color=None, alpha=0.4) bk.text(fakeScatterXtext[1:], fakeScatterY[1:], text=legendCounts[1:], angle=0, text_align="left", text_font_size="7pt", text_baseline='middle') #for i in range(len(fakeScatter)): # bk.scatter([fakeScatter[i]], [fakeScatter[i]], size = [legendCircles[i]], legend = int(legendCircles[i]), color = 'red', fill_line = None, alpha = 0.4) # Disable background grid bk.grid().grid_line_color = None #print centers ### Legend #x = -74.25 #y = 40.8 #height = 0.003 #legend_box_y = y + 0.5 * height * len(legendColors) #bk.rect([x+0.032], [legend_box_y], width = 0.12, height = height*len(legendColors)*1.15, color = "#ffffff", line_color = "gray") ##x = -74.25 ##y = 40.9 #for color in legendColors: ## #print "Color: ", a ## #print "x:", x ## #print "y:", y ## # bk.rect([x], [y], color = color, width=0.03, height=height) # #bk.text([x], [y], text = agency, angle=0, text_font_size="7pt", text_align="center", text_baseline="middle") # y = y + height #legend_bottom_y = 40.797 #legend_top_y = legend_bottom_y + 0.92 * height * len(legendColors) #bk.text([-74.225], [legend_bottom_y], text = agency2, angle = 0, text_font_size = "7pt", text_align = "left") #bk.text([-74.225], [legend_top_y], text = agency1, angle = 0, text_font_size = "7pt", text_align = "left") #bokeh.embed.components(fig, bokeh.resources.CDN) bk.show()
# Set x-y ranges x_range = [str(x) for x in range(-1,11)] y_range = [str(y) for y in range(-1,-11)] # Make a rect glyph for each factor bk.rect("xpos","ypos",0.9,0.9,source=source, x_range=x_range, y_range=y_range, fill_alpha=0.6, color="color_prime", tools="resize", title="Prime Factor Visualization" ) # Add text to display the number for each box # Use text_props = dict to set properties of text elements text_props = { "source": source, "angle": 0, "color": "black", "text_align": "center", "text_baseline": "middle" } bk.text(x=dict(field="xpos", units="data"), y=dict(field="ypos", units="data"), text=dict(field="number", units="data"), text_font_style="bold", text_font_size="12pt", **text_props) # turn off grid lines - bk.grid().grid_line_color = None bk.grid().grid_line_color = None # show the chart bk.show()
tools="resize,hover,previewsave,ywheel_zoom", title="ESS Lab Layout", plot_width=1600, plot_height=3200 ) # Use text_props = dict to set properties of text elements text_props = { "source": source, "angle": 0, "color": "black", "text_align": "center", "text_baseline": "middle" } # Make a text glyph for each rect glyph to show the cabinet names and locations bk.text(x=dict(field="posx", units="data"), y=dict(field="text_locy", units="data"), text=dict(field="loc", units="data"), text_font_style="bold", text_font_size="12pt", **text_props) bk.text(x=dict(field="posx", units="data"), y=dict(field="text_namey", units="data"), text=dict(field="name", units="data"), text_font_style="bold", text_font_size="9pt", **text_props) bk.text(x=dict(field="posx", units="data"), y=dict(field="text_suby", units="data"), text=dict(field="sub", units="data"), text_font_style="bold", text_font_size="9pt", **text_props) # turn off grid lines bk.grid().grid_line_color = None # Add hovertool to show equipment in tooltips
def make_box_violin_plot_2(data, maxwidth=0.9): """ data: dict[Str -> List[Number]] maxwidth: float Maximum width of tornado plot within each factor/facet Returns the plot object """ df = pd.DataFrame(columns=["group", "centers", "width", "height", "texts"]) bar_height = 50 bins = [0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6] # Compute histograms, while keeping track of max Y values and max counts for i, (group, vals) in enumerate(data.iteritems()): hist, edges = np.histogram(vals, bins) df = df.append( pd.DataFrame( dict( group=group, centers=np.arange(len(hist)) * bar_height, width=np.log10(hist), height=np.ones(hist.shape) * bar_height, texts=map(str, hist), ))) df.replace(-np.inf, 0) # Normalize the widths df["width"] *= (maxwidth / df["width"].max()) hold() width, height = 800, 800 figure(plot_width=width, plot_height=height, title="Degree Distribution", tools="previewsave", x_axis_type=None, y_axis_type=None, x_range=[-420, 420], y_range=[-420, 420], x_axis_label="Number of nodes (log)", y_label="distribution of degree", min_border=0, outline_line_color=None, background_fill="#f0e1d2", border_fill="#f0e1d2") size = len(df) rect(np.zeros(size), df["centers"], height=[50 for i in range(size)], width=df["width"] * width * .8) text(np.zeros(size), df["centers"], text=df["texts"], angle=np.zeros(size), text_color=["#000000"] + ["#FFFFFF" for i in xrange(size - 1)], text_align="center", text_baseline="middle") text(np.ones(size + 1) * -width / 2, [(idx - 0.75) * bar_height for idx in range(size + 1)], text=map(str, map(int, bins)), angle=0) show()