def add_axes(plot): from bokeh.models import ( CategoricalAxis, Grid, ) x_axis = CategoricalAxis(major_label_orientation=0.785, major_label_text_font=MONO_FONT) y_axis = CategoricalAxis(major_label_text_font=MONO_FONT) plot.add_layout(x_axis, 'below') plot.add_layout(y_axis, 'left') plot.add_layout(Grid(dimension=0, ticker=x_axis.ticker)) plot.add_layout(Grid(dimension=1, ticker=y_axis.ticker))
def pyramid(): xdr = DataRange1d() ydr = FactorRange(factors=groups) plot = Plot(x_range=xdr, y_range=ydr, plot_width=600, plot_height=500, toolbar_location=None) xaxis = LinearAxis() plot.add_layout(xaxis, 'below') plot.add_layout(CategoricalAxis(), 'left') plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker)) m = HBar(left="value", right=0, y="group", height=1, fill_color="#3B8686") mglyph = plot.add_glyph(source_pyramid_m, m) f = HBar(left=0, right="value", y="group", height=1, fill_color="#CFF09E") fglyph = plot.add_glyph(source_pyramid_f, f) plot.add_layout(Legend(items=[("Male", [mglyph]), ("Female", [fglyph])])) return plot
def population(): xdr = FactorRange(factors=years) ydr = DataRange1d() plot = Plot(title=None, x_range=xdr, y_range=ydr, plot_width=800, plot_height=200) plot.add_layout(CategoricalAxis(major_label_orientation=pi / 4), 'below') line_known = Line(x="x", y="y", line_color="violet", line_width=2) line_known_glyph = plot.add_glyph(source_known, line_known) line_predicted = Line(x="x", y="y", line_color="violet", line_width=2, line_dash="dashed") line_predicted_glyph = plot.add_glyph(source_predicted, line_predicted) plot.add_layout( Legend( location="bottom_right", legends=[("known", [line_known_glyph]), ("predicted", [line_predicted_glyph])], )) return plot
def jobtype_builder(): jtypes = ["Half Time", "Full Time", "Hourly", "Temporary"] xdr = FactorRange(factors=jtypes) ydr = DataRange1d(sources=[source_jobtype.columns("data_range")]) plot = Plot(title="Job Type", data_sources=[source_jobtype], x_range=xdr, y_range=ydr, plot_width=760, plot_height=500) xaxis = CategoricalAxis(plot=plot, dimension=0, major_label_orientation=pi / 4.0) yaxis = LinearAxis(plot=plot, dimension=1) yaxis.major_tick_in = 0 ygrid = Grid(plot=plot, dimension=1, axis=yaxis) quad = Rect(x="jobtypes", y="jobtype_half", height="count", width=0.9, fill_color="#33A6A4") bars = Glyph(data_source=source_jobtype, xdata_range=xdr, ydata_range=ydr, glyph=quad) plot.renderers.append(bars) plot.background_fill = '#686975' return plot
def weekday_builder(): dow = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ] xdr = FactorRange(factors=dow) ydr = DataRange1d(sources=[source_dow.columns("data_range")]) plot = Plot(title="Weekday of Job Posting", data_sources=[source_dow], x_range=xdr, y_range=ydr, plot_width=760, plot_height=500) xaxis = CategoricalAxis(plot=plot, dimension=0, major_label_orientation=pi / 4.0) yaxis = LinearAxis(plot=plot, dimension=1) yaxis.major_tick_in = 0 ygrid = Grid(plot=plot, dimension=1, axis=yaxis) quad = Rect(x="weekday", y="weekday_half", height="count", width=0.9, fill_color="#D9301A") bars = Glyph(data_source=source_dow, xdata_range=xdr, ydata_range=ydr, glyph=quad) plot.renderers.append(bars) plot.background_fill = '#686975' return plot
def job_loc_plot_builder(): xdr = FactorRange(factors=countries) ydr = DataRange1d(sources=[source_country.columns("data_range")]) plot = Plot(title="Postings by Job Location (Country)", data_sources=[source_country], x_range=xdr, y_range=ydr, plot_width=760, plot_height=500) xaxis = CategoricalAxis(plot=plot, dimension=0, major_label_orientation=pi / 4.0) yaxis = LinearAxis(plot=plot, dimension=1) yaxis.major_tick_in = 0 ygrid = Grid(plot=plot, dimension=1, axis=yaxis) quad = Rect(x="country", y="count_half", height="count", width=0.9, fill_color="#483D8B") bars = Glyph(data_source=source_country, xdata_range=xdr, ydata_range=ydr, glyph=quad) plot.renderers.append(bars) plot.background_fill = '#333333' return plot
def topicplot(): xdr = DataRange1d(sources=[topicsource.columns("width")]) ydr = FactorRange(factors=list(reversed(list(barDefault2.Term)))) #"Top-{R} Most Relevant Terms for Topic {topic} ({count}% of tokens)".format(R=R, ...) title = "Top-{R} Most Salient Terms".format(R=R) plot = Plot(title=title, title_text_font_size="16px", x_range=xdr, y_range=ydr, plot_width=mdswidth, plot_height=mdsheight) plot.add_glyph( topicsource, Rect(x="x", y="y", width="width", height=1, fill_color=base_color, fill_alpha=0.2, line_color=base_color)) plot.add_layout(LinearAxis(), "above") plot.add_layout(CategoricalAxis(), "left") return plot
def population(): xdr = FactorRange(factors=years) ydr = DataRange1d() plot = Plot(x_range=xdr, y_range=ydr, plot_width=600, plot_height=150, toolbar_location=None) plot.add_layout(CategoricalAxis(major_label_orientation=pi / 4), 'below') known = Line(x="x", y="y", line_color="violet", line_width=2) known_glyph = plot.add_glyph(source_known, known) predicted = Line(x="x", y="y", line_color="violet", line_width=2, line_dash="dashed") predicted_glyph = plot.add_glyph(source_predicted, predicted) legend = Legend(location="bottom_right", items=[("known", [known_glyph]), ("predicted", [predicted_glyph])]) plot.add_layout(legend) return plot
def make_axis(self, dim, location, scale, label): """Create linear, date or categorical axis depending on the location, scale and with the proper labels. Args: location(str): the space localization of the axis. It can be ``left``, ``right``, ``above`` or ``below``. scale (str): the scale on the axis. It can be ``linear``, ``datetime`` or ``categorical``. label (str): the label on the axis. Return: Axis: Axis instance """ # ToDo: revisit how to handle multiple ranges # set the last range to the chart's range if len(self._ranges[dim]) == 0: raise ValueError('Ranges must be added to derive axis type.') data_range = self._ranges[dim][-1] setattr(self, dim + '_range', data_range) if scale == "auto": if isinstance(data_range, FactorRange): scale = 'categorical' else: scale = 'linear' if scale == "linear": axis = LinearAxis(axis_label=label) elif scale == "datetime": axis = DatetimeAxis(axis_label=label) elif scale == "categorical": axis = CategoricalAxis( major_label_orientation=np.pi / 4, axis_label=label ) else: axis = LinearAxis(axis_label=label) self.add_layout(axis, location) return axis
def site_tld_bar(df, plot_width=325, plot_height=200): bars = df[['tld','url']].groupby('tld').count().sort_values('url', ascending=False) bars['y'] = bars.url / 2. source = ColumnDataSource(bars) plot = Plot(title="Most Common Top-level Domains", plot_width=plot_width, plot_height=plot_height, x_range=Range1d(0,bars.url.max()), y_range=FactorRange(factors=bars.index.tolist()[::-1]), **PLOT_FORMATS) plot.add_glyph( source, Rect(x='y', y='tld', height=0.8, width='url', fill_color=BLUE, fill_alpha=0.6, line_color=None) ) plot.add_layout(LinearAxis(axis_label="Occurences", **AXIS_FORMATS), 'below') plot.add_layout(CategoricalAxis(**AXIS_FORMATS), 'left') return plot
def most_common_url_bar(df, plot_width=400, plot_height=250, top_n=None): bars = df[['hostname','url']].groupby('hostname').count().sort_values('url', ascending=False) bars['y'] = bars.url / 2. if top_n: bars = bars.nlargest(top_n, 'url') source = ColumnDataSource(bars) plot = Plot(title="Most Common Sites", plot_width=plot_width, plot_height=plot_height, x_range=Range1d(0,bars.url.max()), y_range=FactorRange(factors=bars.index.tolist()[::-1]), **PLOT_FORMATS) plot.add_glyph( source, Rect(x='y', y='hostname', height=0.8, width='url', fill_color=BLUE, fill_alpha=0.6, line_color=None) ) plot.add_layout(LinearAxis(axis_label="Occurences", **AXIS_FORMATS), 'below') plot.add_layout(CategoricalAxis(**AXIS_FORMATS), 'left') return plot
x_range = FactorRange(factors=df["Tool"].drop_duplicates().tolist()) choose_color = 0 for c in df.sort_values(by="Category")["Category"].drop_duplicates().tolist(): df.loc[df.Category == c, "color"] = palette[choose_color] choose_color += 1 source = ColumnDataSource( data=dict(tool=df["Tool"].tolist(), feature=df[["Category", "Features"]].values.tolist(), color=df["color"].tolist(), category=df["Category"].tolist(), desc=df["Definition"].tolist())) hover = HoverTool(tooltips=[("Tool", "@tool"), ("Feature Definition", "@desc")]) p = figure(x_range=x_range, y_range=y_range, plot_height=7500, plot_width=1500, x_axis_location="above", tools=[hover]) p.circle(x="tool", y="feature", color="black", source=source, size=28) p.add_layout(CategoricalAxis(), 'below') p.xaxis.major_label_text_font_size = "12pt" p.yaxis.major_label_text_font_size = "12pt"
def make_calendar(year, month, firstweekday="Mon"): firstweekday = list(day_abbrs).index(firstweekday) calendar = Calendar(firstweekday=firstweekday) month_days = [ None if not day else str(day) for day in calendar.itermonthdays(year, month) ] month_weeks = len(month_days)//7 workday = "linen" weekend = "lightsteelblue" def weekday(date): return (date.weekday() - firstweekday) % 7 def pick_weekdays(days): return [ days[i % 7] for i in range(firstweekday, firstweekday+7) ] day_names = pick_weekdays(day_abbrs) week_days = pick_weekdays([workday]*5 + [weekend]*2) source = ColumnDataSource(data=dict( days = list(day_names)*month_weeks, weeks = sum([ [str(week)]*7 for week in range(month_weeks) ], []), month_days = month_days, day_backgrounds = sum([week_days]*month_weeks, []), )) holidays = [ (date, summary.replace("(US-OPM)", "").strip()) for (date, summary) in us_holidays if date.year == year and date.month == month and "(US-OPM)" in summary ] holidays_source = ColumnDataSource(data=dict( holidays_days = [ day_names[weekday(date)] for date, _ in holidays ], holidays_weeks = [ str((weekday(date.replace(day=1)) + date.day) // 7) for date, _ in holidays ], month_holidays = [ summary for _, summary in holidays ], )) xdr = FactorRange(factors=list(day_names)) ydr = FactorRange(factors=list(reversed([ str(week) for week in range(month_weeks) ]))) x_scale, y_scale = CategoricalScale(), CategoricalScale() plot = Plot(x_range=xdr, y_range=ydr, x_scale=x_scale, y_scale=y_scale, plot_width=300, plot_height=300, outline_line_color=None) plot.title.text = month_names[month] plot.title.text_font_size = "16px" plot.title.text_color = "darkolivegreen" plot.title.offset = 25 plot.min_border_left = 0 plot.min_border_bottom = 5 rect = Rect(x="days", y="weeks", width=0.9, height=0.9, fill_color="day_backgrounds", line_color="silver") plot.add_glyph(source, rect) rect = Rect(x="holidays_days", y="holidays_weeks", width=0.9, height=0.9, fill_color="pink", line_color="indianred") rect_renderer = plot.add_glyph(holidays_source, rect) text = Text(x="days", y="weeks", text="month_days", text_align="center", text_baseline="middle") plot.add_glyph(source, text) xaxis = CategoricalAxis() xaxis.major_label_text_font_size = "11px" xaxis.major_label_standoff = 0 xaxis.major_tick_line_color = None xaxis.axis_line_color = None plot.add_layout(xaxis, 'above') hover_tool = HoverTool(renderers=[rect_renderer], tooltips=[("Holiday", "@month_holidays")]) plot.tools.append(hover_tool) return plot
def generate_bar(dataset, plot_height, dimension_name, measure_name, measure_label_name=None, measure_label_function=None, category_field=None, fill_color=None, line_color=None, dimension_type="continuous", max_dimension_range=None, dimension_interval=2, goals_dataset=None, goal_measure_type="absolute", goal_dimension_type="value", goal_label_function=None, tap_tool_callback=None): # IMPORTANT: Assumes that data is ordered descending by dimension values when working out the axis range, use inverse for ascending dimension_values = [] dimension_labels = [] measure_values = [] measure_labels = [] fill_colors = [] line_colors = [] if measure_label_name is None: measure_label_name = measure_name for row in dataset: if dimension_type=="timedelta": dimension_values.append(utils.seconds_to_datetime(getattr(row, dimension_name))) dimension_labels.append(utils.convert_seconds_to_minutes_formatted(getattr(row, dimension_name))) else: dimension_values.append(getattr(row, dimension_name)) dimension_labels.append(getattr(row, dimension_name)) measure_values.append(getattr(row, measure_name)) if measure_label_function is None: measure_labels.append(getattr(row, measure_label_name)) else: measure_labels.append(measure_label_function(getattr(row, measure_label_name))) if category_field is not None: fill_colors.append(getattr(row, category_field).fill_color if getattr(row, category_field) is not None else "#292b2c") line_colors.append(getattr(row, category_field).line_color if getattr(row, category_field) is not None else "#292b2c") elif fill_color is not None: fill_colors.append(fill_color), line_colors.append(line_color) else: fill_colors.append("#292b2c") line_colors.append("#292b2c") source=ColumnDataSource(dict(dimension=dimension_values, dimension_label=dimension_labels, measure=measure_values, measure_label=measure_labels, fill_color=fill_colors, line_color=line_colors)) # Set the dimension ranges without knowledge of goal targets for now if dimension_type == "continuous": if max_dimension_range is None: dimension_range_min = dimension_values[-1] dimension_range_max = dimension_values[0] else: dimension_range_min = dimension_values[-1] if dimension_values[-1] > max_dimension_range[0] else max_dimension_range[0] dimension_range_max = dimension_values[0] if dimension_values[0] < max_dimension_range[1] else max_dimension_range[1] elif dimension_type == "timedelta": if max_dimension_range is None: dimension_range_min = dimension_values[-1] dimension_range_max = dimension_values[0] else: dimension_range_min = dimension_values[-1] if dimension_values[-1] > max_dimension_range[0] else max_dimension_range[0] dimension_range_max = dimension_values[0] if dimension_values[0] < max_dimension_range[1] else max_dimension_range[1] measure_range_max = max(measure_values) # Prep the goals data if we have any if goals_dataset is not None: goals_source = prepare_goals_source(goals_dataset=goals_dataset, goal_dimension_type=goal_dimension_type, goal_measure_type=goal_measure_type, measure_label_function=measure_label_function, goal_label_function=goal_label_function) # Update the max ranges if dimension_type == "continuous": if min(goals_source.data["dimension"]) < dimension_range_min: dimension_range_min = min(goals_source.data["dimension"])-1 if max(goals_source.data["dimension"]) > dimension_range_max: dimension_range_max = max(goals_source.data["dimension"])+1 if max(goals_source.data["measure"]) > measure_range_max: measure_range_max = max(goals_source.data["measure"]) if dimension_type == "continuous": dimension_range = (dimension_range_min-1, dimension_range_max+1) bar_height = 0.6 * dimension_interval goal_bar_height = 0.9 * dimension_interval elif dimension_type == "timedelta": dimension_range = (dimension_range_max+timedelta(seconds=2.5), dimension_range_min-timedelta(seconds=2.5)) bar_height = 0.6 * dimension_interval goal_bar_height = 0.9 * dimension_interval elif dimension_type == "discrete": dimension_range = dimension_values bar_height = 0.6 goal_bar_height = 0.8 measure_range = (-1, float(measure_range_max)*1.3) # Ideally this would be more responsive for the viewport but need to look at options if dimension_type=="timedelta": plot = figure(plot_height=plot_height, y_axis_type="datetime", y_range=dimension_range, x_range=measure_range, tooltips="@dimension_label: @measure_label", toolbar_location=None, tools=["tap"]) plot.yaxis.formatter=DatetimeTickFormatter(minsec='%M:%S') else: plot = figure(plot_height=plot_height, y_range=dimension_range, x_range=measure_range, toolbar_location=None, tooltips="@dimension: @measure_label", y_axis_type=None, tools=["tap"]) plot.hbar(source=source, y="dimension", right="measure", height=bar_height, color="fill_color", line_color="line_color", fill_alpha=0.8, hover_color="fill_color", hover_alpha=1) labels = LabelSet(source=source, x="measure", y="dimension", text="measure_label", level="glyph", x_offset=5, y_offset=-5, render_mode="canvas", text_font = "sans-serif", text_font_size = "7pt", text_color="fill_color") plot.add_layout(labels) # Add dashed lines for any goal targets that are set if goals_dataset is not None: plot.hbar(source=goals_source, y="dimension", right="measure", height=goal_bar_height, fill_alpha=0, line_color="#666666") goal_labels = LabelSet(source=goals_source, x="measure", y="dimension", text="measure_label", level="glyph", x_offset=5, y_offset=-5, render_mode="canvas", text_font = "sans-serif", text_font_size = "7pt", text_color="#666666") plot.add_layout(goal_labels) else: goals_source = None if tap_tool_callback is not None: tap_tool = plot.select(type=TapTool) tap_tool.callback = CustomJS(args=dict(source=source, goals_source=goals_source), code=tap_tool_callback) # TODO: This will need to be more flexible for data other than cadence if dimension_type == "continuous": y_ticker = SingleIntervalTicker(interval=2*dimension_interval, num_minor_ticks=2) y_axis = LinearAxis(ticker=y_ticker) plot.add_layout(y_axis, "left") elif dimension_type == "timedelta": pass else: y_axis = CategoricalAxis() plot.add_layout(y_axis, "left") plot.xaxis.visible = False plot.sizing_mode = "scale_width" plot.axis.minor_tick_line_color = None plot.axis.axis_line_color = "#999999" plot.axis.major_label_text_color = "#666666" plot.axis.major_label_text_font_size = "7pt" plot.axis.major_tick_line_color = "#999999" plot.grid.grid_line_color = None plot.outline_line_color = None return plot
text_font_style='italic', text=['net tax increase'], text_font_size='8pt', text_color='#666666')) bars.add_glyph(bars_source, Text(x='annotation_x', y='annotation_y', text='annotation', text_font_style='italic', text_font_size='8pt', text_color=DARK_GRAY)) #bars.add_layout(LinearAxis(**AXIS_FORMATS), 'below') #bars.add_layout(LinearAxis(**AXIS_FORMATS), 'left') bars.add_layout(CategoricalAxis(axis_label="Annual Adjusted Gross Income", **AXIS_FORMATS), 'left') # create text plots ------------------------------------- taxcut_source = ColumnDataSource(taxcut_sources['ds_000_taxcut'].data) percentcut_text = Plot(plot_width=800, plot_height=text_plot_height, x_range=Range1d(0, 100), y_range=Range1d(0, 100), **PLOT_FORMATS) textbottom_renderer = percentcut_text.add_glyph(taxcut_source, Text(x=3.15, y=10, text_font_style='normal', text='text',
def make_bokeh_cat_float_scat(self, p, df, cat_order, title='Needs Title', xlabel='Needs xlabel', ylabel='Needs ylabel', cat_color='navy'): '''Make a simple bokeh scatter plot with categorical on y axis. Has simple controls for scaling, positioning, and reset. Assumes a figure p pre-established df is a dataframe with: xvalues in column 0 float values in columns 1 to col_max-1 cat values in col_max cat_order is an ordered list that aligns cat axis and contains axis_labelunique categories titles/labels are simple strings''' from bokeh.palettes import brewer from bokeh.models import ColumnDataSource,\ Legend, LegendItem, LinearAxis,FactorRange,\ CategoricalAxis data_names = df.columns colors = brewer['RdBu'][4] legend_items = [] for y in range(1, len(data_names)): color = colors[y % 4] r = p.circle(x=df.iloc[:, 0], y=df.iloc[:, y], size=7.5, color=color) #items.append((data_names[y],[r])) legend_items.append(LegendItem(label=data_names[y], renderers=[r])) #Set second y_axis print(type(cat_order), cat_order) p.extra_y_ranges = {"cat_ax": FactorRange(factors=cat_order)} #Add second y axis p.add_layout(CategoricalAxis(y_range_name="cat_ax"), "right") last_col = len(df.columns) - 1 r = p.circle(x=df.iloc[:, 0], y=df.iloc[:, last_col], y_range_name="cat_ax", size=7.5, color=cat_color) legend_items.append( LegendItem(label=data_names[last_col], renderers=[r])) p.xaxis.axis_label = xlabel p.yaxis.axis_label = ylabel p.title.text = title legend1 = Legend(items=legend_items, location='center') p.add_layout(legend1, 'right') p.legend.click_policy = "hide" return p
xdr = FactorRange(factors=list(css3_colors.Group.unique())) ydr = FactorRange(factors=list(reversed(css3_colors.Name))) plot = Plot(x_range=xdr, y_range=ydr, plot_width=600, plot_height=2000) plot.title.text = "CSS3 Color Names" rect = Rect(x="groups", y="names", width=1, height=1, fill_color="colors", line_color=None) rect_renderer = plot.add_glyph(source, rect) xaxis_above = CategoricalAxis(major_label_orientation=pi / 4) plot.add_layout(xaxis_above, 'above') xaxis_below = CategoricalAxis(major_label_orientation=pi / 4) plot.add_layout(xaxis_below, 'below') plot.add_layout(CategoricalAxis(), 'left') url = "http://www.colors.commutercreative.com/@names/" tooltips = """Click the color to go to:<br /><a href="{url}">{url}</a>""".format( url=url) tap = TapTool(plot=plot, renderers=[rect_renderer], callback=OpenURL(url=url)) hover = HoverTool(plot=plot, renderers=[rect_renderer], tooltips=tooltips) plot.tools.extend([tap, hover])
def make_calendar(year, month, firstweekday="Mon"): firstweekday = list(day_abbrs).index(firstweekday) calendar = Calendar(firstweekday=firstweekday) month_days = [ None if not day else str(day) for day in calendar.itermonthdays(year, month) ] month_weeks = len(month_days)//7 workday = "linen" weekend = "lightsteelblue" def weekday(date): return (date.weekday() - firstweekday) % 7 def pick_weekdays(days): return [ days[i % 7] for i in range(firstweekday, firstweekday+7) ] day_names = pick_weekdays(day_abbrs) week_days = pick_weekdays([workday]*5 + [weekend]*2) source = ColumnDataSource(data=dict( days = list(day_names)*month_weeks, weeks = sum([ [str(week)]*7 for week in range(month_weeks) ], []), month_days = month_days, day_backgrounds = sum([week_days]*month_weeks, []), )) holidays = [ (date, summary.replace("(US-OPM)", "").strip()) for (date, summary) in us_holidays if date.year == year and date.month == month and "(US-OPM)" in summary ] holidays_source = ColumnDataSource(data=dict( holidays_days = [ day_names[weekday(date)] for date, _ in holidays ], holidays_weeks = [ str((weekday(date.replace(day=1)) + date.day) // 7) for date, _ in holidays ], month_holidays = [ summary for _, summary in holidays ], )) xdr = FactorRange(factors=list(day_names)) ydr = FactorRange(factors=list(reversed([ str(week) for week in range(month_weeks) ]))) x_scale, y_scale = CategoricalScale(), CategoricalScale() plot = Plot(x_range=xdr, y_range=ydr, x_scale=x_scale, y_scale=y_scale, plot_width=300, plot_height=300, outline_line_color=None) plot.title.text = month_names[month] plot.title.text_font_size = "12pt" plot.title.text_color = "darkolivegreen" plot.title.offset = 25 plot.min_border_left = 0 plot.min_border_bottom = 5 rect = Rect(x="days", y="weeks", width=0.9, height=0.9, fill_color="day_backgrounds", line_color="silver") plot.add_glyph(source, rect) rect = Rect(x="holidays_days", y="holidays_weeks", width=0.9, height=0.9, fill_color="pink", line_color="indianred") rect_renderer = plot.add_glyph(holidays_source, rect) text = Text(x="days", y="weeks", text="month_days", text_align="center", text_baseline="middle") plot.add_glyph(source, text) xaxis = CategoricalAxis() xaxis.major_label_text_font_size = "8pt" xaxis.major_label_standoff = 0 xaxis.major_tick_line_color = None xaxis.axis_line_color = None plot.add_layout(xaxis, 'above') hover_tool = HoverTool(renderers=[rect_renderer], tooltips=[("Holiday", "@month_holidays")]) plot.tools.append(hover_tool) return plot
def _newaxis(plot, _): plot.state.extra_x_ranges = { "track": FactorRange(*frame.track.values) } plot.state.add_layout(CategoricalAxis(x_range_name="track"), 'above')
def make_calendar(sp500_data_lst, djia_data_lst, nasdaq_data_lst, twitter_data_lst, holiday_lst, nyt_data_lst, approval_data_lst, generic_dem_lst, generic_rep_lst, plot_wid, plot_ht, year, month, firstweekday="Sun"): firstweekday = list(day_abbrs).index(firstweekday) calendar = Calendar(firstweekday=firstweekday) month_days = [ None if not day else str(day) for day in calendar.itermonthdays(year, month) ] month_weeks = len(month_days) // 7 workday = "linen" weekend = "lightsteelblue" def weekday(date): return (date.weekday() - firstweekday) % 7 def pick_weekdays(days): return [days[i % 7] for i in range(firstweekday, firstweekday + 7)] day_names = pick_weekdays(day_abbrs) week_days = pick_weekdays([workday] * 5 + [weekend] * 2) source = ColumnDataSource(data=dict( days=list(day_names) * month_weeks, weeks=sum([[str(week)] * 7 for week in range(month_weeks)], []), month_days=month_days, day_backgrounds=['white'] * len(month_days), )) djia_data = [(dj_date, DJIA) for (dj_date, DJIA) in djia_data_lst if dj_date.year == year and dj_date.month == month] nasdaq_data = [(nas_date, NASDAQCOM) for (nas_date, NASDAQCOM) in nasdaq_data_lst if nas_date.year == year and nas_date.month == month] sp500_data = [(sp500_date, SP500) for (sp500_date, SP500) in sp500_data_lst if sp500_date.year == year and sp500_date.month == month] holidays = [(holiday_date, Holiday) for (holiday_date, Holiday) in holiday_lst if holiday_date.year == year and holiday_date.month == month] twitter_data = [ (twitter_date, topics) for (twitter_date, topics) in twitter_data_lst if twitter_date.year == year and twitter_date.month == month ] nyt_data = [(nyt_date, headlines) for (nyt_date, headlines) in nyt_data_lst if nyt_date.year == year and nyt_date.month == month] approval_data = [ (approval_date, approve_estimate) for (approval_date, approve_estimate) in approval_data_lst if approval_date.year == year and approval_date.month == month ] approval_data.sort() generic_dem = [(generic_date, dem_estimate) for (generic_date, dem_estimate) in generic_dem_lst if generic_date.year == year and generic_date.month == month ] generic_dem.sort() generic_rep = [(generic_date, rep_estimate) for (generic_date, rep_estimate) in generic_rep_lst if generic_date.year == year and generic_date.month == month ] generic_rep.sort() colors_djia = [DJIA for _, DJIA in djia_data] colors_sp500 = [SP500 for _, SP500 in sp500_data] colors_nasdaq = [NASDAQCOM for _, NASDAQCOM in nasdaq_data] for i in range(len(colors_djia) - 1): avg = np.mean([colors_djia[i], colors_sp500[i], colors_nasdaq[i]]) if 0 < avg <= 11000: colors_djia[i] = '#E52700' elif 11000 < avg <= 11100: colors_djia[i] = '#E33A00' elif 11100 < avg <= 11200: colors_djia[i] = '#E14C00' elif 11200 < avg <= 11300: colors_djia[i] = '#DF5E00' elif 11300 < avg <= 11400: colors_djia[i] = '#DD6F00' elif 11400 < avg <= 11500: colors_djia[i] = '#DB8000' elif 11500 < avg <= 11600: colors_djia[i] = '#D99100' elif 11600 < avg <= 11700: colors_djia[i] = '#D7A100' elif 11700 < avg <= 11800: colors_djia[i] = '#D5B100' elif 11800 < avg <= 11900: colors_djia[i] = '#D3C100' elif 11900 < avg <= 12000: colors_djia[i] = '#D1D000' elif 12000 < avg <= 12100: colors_djia[i] = '#BECF00' elif 12200 < avg <= 12300: colors_djia[i] = '#ABCD00' elif 12300 < avg <= 12400: colors_djia[i] = '#99CB00' elif 12400 < avg <= 12500: colors_djia[i] = '#87C900' elif 12500 < avg <= 12600: colors_djia[i] = '#75C700' elif 12500 < avg <= 12600: colors_djia[i] = '#64C500' else: colors_djia[i] = '#53C300' holiday_source = ColumnDataSource(data=dict( month_djia=[DJIA for _, DJIA in djia_data], month_nasdaq=[NASDAQCOM for _, NASDAQCOM in nasdaq_data], month_sp500=[SP500 for _, SP500 in sp500_data], month_twitter=[topics for _, topics in twitter_data], month_holidays=[Holiday for _, Holiday in holidays], nyt_days=[day_names[weekday(nyt_date)] for nyt_date, _ in nyt_data], nyt_weeks=['0'] + [ str((weekday(nyt_date.replace(day=1)) + nyt_date.day) // 7) for nyt_date, _ in nyt_data ], month_nyt=[headlines for _, headlines in nyt_data], month_approval=[ approve_estimate for _, approve_estimate in approval_data ], month_generic_dem=[dem_estimate for _, dem_estimate in generic_dem], month_generic_rep=[rep_estimate for _, rep_estimate in generic_rep], day_backgrounds=colors_djia, )) xdr = FactorRange(factors=list(day_names)) ydr = FactorRange( factors=list(reversed([str(week) for week in range(month_weeks)]))) x_scale, y_scale = CategoricalScale(), CategoricalScale() plot = Plot(x_range=xdr, y_range=ydr, x_scale=x_scale, y_scale=y_scale, plot_width=plot_wid, plot_height=plot_ht) plot.title.text = month_names[month] + " " + str(year) plot.title.text_font_size = "14pt" plot.title.text_color = "black" plot.title.offset = 25 plot.min_border_left = 5 plot.min_border_top = 5 plot.min_border_bottom = 190 plot.border_fill_color = "white" plot.background_fill_alpha = 0.5 plot.border_fill_alpha = 0.3 rect = Rect(x="days", y="weeks", width=0.9, height=0.9, fill_color="day_backgrounds", line_color="silver") plot.add_glyph(source, rect) rect = Rect(x="nyt_days", y="nyt_weeks", width=0.9, fill_color="day_backgrounds", height=0.9) rect_renderer = plot.add_glyph(holiday_source, rect) text = Text(x="days", y="weeks", text="month_days", text_align="center", text_baseline="middle") plot.add_glyph(source, text) xaxis = CategoricalAxis() xaxis.major_label_text_font_size = "10pt" xaxis.major_label_standoff = 0 xaxis.major_tick_line_color = None xaxis.axis_line_color = None plot.add_layout(xaxis, 'above') TOOLTIPS = """ <div style="height:100%; max-width:300px; min-width:200px;background-color: aliceblue; position:relative;"> <div> <span style="font-size: 17px; font-weight: bold;"> Holiday: @month_holidays</span><br> <span style="font-size: 15px; font-weight: bold; color: darkgrey;"> Trump Approval Rating: @month_approval{0,0.0}%</span><br> <span style="font-size: 15px; font-weight: bold; color: blue;"> Generic Democrat: @month_generic_dem{0,0.0}%</span><br> <span style="font-size: 15px; font-weight: bold; color: red;"> Generic Republican: @month_generic_rep{0,0.0}%</span><br> <span style="font-size: 17px; font-weight: bold;"> NASDAQ: @month_nasdaq{0,0.00}</span><br> <span style="font-size: 17px; font-weight: bold;"> DJIA: @month_djia{0,0.00}</span><br> <span style="font-size: 17px; font-weight: bold;">S&P500: @month_sp500{0,0.00}</span><br> </div> <div> <img src="/static/img/nyt_logo.png" height="15" width="15" style="float: left;"></img> </div> <div> <span style="font-size: 17px; font-weight: bold;">NYT Headlines:</span> <span style="font-size: 15px;">@month_nyt</span> </div> <div> <img src="/static/img/twitter_logo.png" height="15" width="15" style="float: left;"></img> </div> <div> <span style="font-size: 17px; color:blue; font-weight: bold;">Trending Tweets:</span> <span style="font-size: 15px; color:blue;">@month_twitter</span> </div> </div> """ hover_tool = HoverTool(renderers=[rect_renderer], tooltips=TOOLTIPS) # hover_tool = HoverTool(renderers=[rect_renderer], tooltips=[("Holiday", "@month_holidays"),("DJIA", "@month_djia{0,0.00}"), # ("NASDAQ", "@month_nasdaq{0,0.00}"),("S&P500", "@month_sp500{0,0.00}"),("NYT Headlines", "@month_nyt"),("Trending Tweets","@month_twitter")]) plot.tools.append(hover_tool) return plot