def draw_target_chart(self, targets_dates, targets_data, total_dates, total_data, age_dates, age_data, title_str, plt_width, plt_height, y_unit, x_unit, save_to_file): """ Draws trent chart :param title_str: title of the chart :param plt_width: width of the canvas :param plt_height: height of the canvas :param y_unit: unit of the y ax :param save_to_file: path to save chart to :return: """ ayer = ArrayMapHelper() mather = MathHelper() colors = [(31, 119, 180), (255, 127, 14), (174, 199, 232)] for i in range(len(colors)): r, g, b = colors[i] colors[i] = (r / 255., g / 255., b / 255.) plt.figure(figsize=(plt_width, plt_height)) # The fig is divided into one row * one colum sub fig, and this is the first picture of this fig. ax = plt.subplot(111) # Hide the right and top spines ax.spines["top"].set_visible(False) # ax.spines["bottom"].set_visible(False) ax.spines["right"].set_visible(False) # ax.spines["left"].set_visible(False) # Only show ticks on the left and bottom spines ax.get_xaxis().tick_bottom() ax.get_yaxis().tick_left() datemin = time.strptime(targets_dates[0], '%m/%d/%Y') datemin = datetime.date(datemin.tm_year, datemin.tm_mon, datemin.tm_mday) datemax = time.strptime(targets_dates[-1], '%m/%d/%Y') datemax = datetime.date(datemax.tm_year, datemax.tm_mon, datemax.tm_mday) ax.set_xlim(datemin, datemax) if x_unit == "monthly": xus = mdates.MonthLocator() xusFmt = mdates.DateFormatter('%m/%Y') ax.xaxis.set_major_locator(xus) ax.xaxis.set_major_formatter(xusFmt) plt.xticks(fontsize=8) elif x_unit == "weekly": x_p = [] x_l = [] tmp = datemin while tmp <= datemax: x_p.append(tmp) x_l.append(tmp.strftime('%m/%d/%Y')) tmp += datetime.timedelta(7) ax.set_xlim(datemin, datemax) plt.xticks(x_p, x_l, fontsize=8) elif x_unit == "daily": x_p = [] x_l = [] tmp = datemin while tmp <= datemax: x_p.append(tmp) x_l.append(tmp.strftime('%m/%d/%Y')) tmp += datetime.timedelta(1) ax.set_xlim(datemin, datemax) plt.xticks(x_p, x_l, fontsize=8) # why only set_minor_locator and set twice ?? # refrence: http://www.voidcn.com/blog/silentwater/article/p-5754552.html # days = mdates.DayLocator() # ax.xaxis.set_minor_locator(days) # ax.grid(True) # xus = mdates.MonthLocator() # xusFmt = mdates.DateFormatter('%m/%Y') # ax.xaxis.set_major_locator(xus) # ax.xaxis.set_major_formatter(xusFmt) # plt.xticks(fontsize=8) days = mdates.WeekdayLocator() ax.xaxis.set_minor_locator(days) ax.grid(True) plt.tick_params(axis="both", which="both", bottom="on", top="off", labelbottom="on", left="off", right="off", labelleft="on") mins = [] maxs = [] min_v, max_v = self._draw_line(targets_dates, targets_data, datemax, colors[0], True) mins.append(min_v) maxs.append(max_v) # total_datemax = time.strptime(total_dates[-1],'%m/%d/%Y') # total_datemax =datetime.date(total_datemax.tm_year,total_datemax.tm_mon,total_datemax.tm_mday) # min_v,max_v = self._draw_line(total_dates,total_data,total_datemax,colors[1]) # mins.append(min_v) # maxs.append(max_v) age_datemax = time.strptime(age_dates[-1], '%m/%d/%Y') age_datemax = datetime.date(age_datemax.tm_year, age_datemax.tm_mon, age_datemax.tm_mday) min_v, max_v = self._draw_line(age_dates, age_data, age_datemax, colors[1]) mins.append(min_v) maxs.append(max_v) y_min, yminminp, yminmax, yminmaxp = ayer.get_array_min_max_index_value( mins) y_max_min, y_maxminp, y_max, y_maxmaxp = ayer.get_array_min_max_index_value( maxs) y_floor = mather.ffloor(int(y_min), y_unit) y_roof = mather.rroof(int(y_max), y_unit) + y_unit plt.text(datemax - datetime.timedelta(len(targets_dates) * 7 / 5), y_roof, "Target", fontsize=8, color=colors[0]) # plt.text(datemax - datetime.timedelta(len(targets_dates)*7/5), y_roof - y_unit, "Domain Total", fontsize=8, color=colors[1]) plt.text(datemax - datetime.timedelta(len(targets_dates) * 7 / 5), y_roof - y_unit, "Actual", fontsize=8, color=colors[1]) plt.ylim(y_floor, y_roof + y_unit / 2) plt.yticks( range(y_floor, y_roof + y_unit / 2, y_unit), [str(x) for x in range(y_floor, y_roof + y_unit / 2, y_unit)], fontsize=8) plt.title(title_str, loc='left') plt.savefig(save_to_file, bbox_inches='tight')
ax = opsd_dailyN.loc['2017', 'Consumption'].plot() ax.set_ylabel('Daily Consumption (GWh)') #zoom in further and look at just January and February ax = opsd_dailyN.loc['2017-01':'2017-02', 'Consumption'].plot(marker='o', linestyle='-') ax.set_ylabel('Daily Consumption (GWh)') #to have vertical gridlines on a weekly time scale import matplotlib.dates as mdates fig, ax = plt.subplots() ax.plot(opsd_dailyN.loc['2017-01':'2017-02', 'Consumption'], marker='o', linestyle='-') ax.set_ylabel('Daily Consumption (GWh)') ax.set_title('Jan-Feb 2017 Electricity Consumption') # Set x-axis major ticks to weekly interval, on Mondays ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.MONDAY)) # Format x-tick labels as 3-letter month name and day number ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) #To explore the seasonality of our data with box plots, using seaborn’s boxplot() function to group # the data by different #time periods and display the distributions for each group. fig, axes = plt.subplots(3, 1, figsize=(11, 10), sharex=True) for name, ax in zip(['Consumption', 'Solar', 'Wind'], axes): sns.boxplot(data=opsd_dailyN, x='Month', y=name, ax=ax) ax.set_ylabel('GWh') ax.set_title(name) # Remove the automatic x-axis label from all but the bottom subplot if ax != axes[-1]: ax.set_xlabel('')
def plot_backtest(config, algos, labels=None): """ @:param config: config dictionary @:param algos: list of strings representing the name of algorithms or index of pgportfolio result """ results = [] for i, algo in enumerate(algos): if algo.isdigit(): results.append(np.cumprod(_load_from_summary(algo, config))) logging.info("load index " + algo + " from csv file") else: logging.info("start executing " + algo) results.append(np.cumprod(execute_backtest(algo, config))) logging.info("finish executing " + algo) start, end = _extract_test(config) timestamps = np.linspace(start, end, len(results[0])) dates = [ datetime.datetime.fromtimestamp( int(ts) - int(ts) % config["input"]["global_period"]) for ts in timestamps ] weeks = mdates.WeekdayLocator() days = mdates.DayLocator() hours = mdates.HourLocator() rc("font", **{ "family": "sans-serif", "sans-serif": ["Helvetica"], "size": 8 }) """ styles = [("-", None), ("--", None), ("", "+"), (":", None), ("", "o"), ("", "v"), ("", "*")] """ fig, ax = plt.subplots() fig.set_size_inches(9, 5) for i, pvs in enumerate(results): if len(labels) > i: label = labels[i] else: label = NAMES[algos[i]] ax.semilogy(dates, pvs, linewidth=1, label=label) #ax.plot(dates, pvs, linewidth=1, label=label) plt.ylabel("portfolio value $p_t/p_0$", fontsize=12) plt.xlabel("time", fontsize=12) xfmt = mdates.DateFormatter("%y-%m-%d %H:%M") datemin = dates[0] datemax = dates[-1] ax.set_xlim(datemin, datemax) ax.xaxis.set_major_formatter(xfmt) plt.grid(True) try: ax.xaxis.set_major_locator(days) ax.xaxis.set_minor_locator(hours) plt.tight_layout() except RuntimeError: ax.xaxis.set_major_locator(weeks) ax.xaxis.set_minor_locator(days) plt.tight_layout() ax.legend(loc="upper left", prop={"size": 10}) fig.autofmt_xdate() plt.savefig("result.eps", bbox_inches='tight', pad_inches=0) plt.show()
# Add the x-axis and the y-axis to the plot ax.plot(summer_data.index, summer_ozone, '-', color='purple') #to look at the data with logrithmic scale #ax.semilogy(summer_data.index, #ozone_data, '-', #color='purple') # Set title and labels for axes ax.set(xlabel="Date and time", ylabel="Ozone / ppb", title="Summer Ozone levels") # Clean up the x axis dates ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=1)) ax.xaxis.set_major_formatter(DateFormatter("%d/%m")) axes = plt.gca() axes.set_ylim([0, 160]) plt.show() #%% autumn ozone autumn_data = pd.read_csv( '/home/lp555/Delhi/Observations/BHAM_IIT_autumn_ozone_final_edited.csv', index_col=['date']) autumn_data.index = pd.to_datetime(autumn_data.index, dayfirst=True) autumn_ozone = pd.DataFrame(autumn_data, columns=['O3']) #%% make the plot fig, ax = plt.subplots(figsize=(18, 10))
dict_gantt[bar], # data (10 * (i + 1), bar_size), # (y position, bar size) alpha=0.75, facecolors=[ colors_dict[event] for event in Totalframe.loc[mask].Nightflight ], edgecolor='k', linewidth=1.2) # I got date formatting ideas from # https://matplotlib.org/examples/pylab_examples/finance_demo.html ax.set_xlim(start_datetime, end_datetime) ax.xaxis.set_major_locator(mdates.HourLocator( byhour=range(0, 24, 24))) # HourLocator(byhour=range(0, 24, 6)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M')) ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=range(0, 24, 1))) # omitting minor labels ... # plt.grid(b=True, which='minor', color='r', linestyle='solid') ax.set_yticks([5 + 10 * n for n in range(1, n + 1)]) ax.set_ylim(5, 5 + 10 * (n + 1)) ax.set_yticklabels(FltReg_list) ax.set_title('Roster') ax.set_ylabel('Task Sort') plt.setp(plt.gca().get_xticklabels(), rotation=30, horizontalalignment='right') plt.tight_layout() fig.show('gantt.png')
ax.xaxis.grid(True) # Major Axis ax.xaxis.set_major_locator(dates.MonthLocator()) ax.xaxis.set_major_formatter(dates.DateFormatter('\n\n\n\n%Y--%B')) fig.autofmt_xdate() # Auto fixes the overlap! plt.tight_layout() plt.show() # ## Minor Axis # In[23]: fig, ax = plt.subplots() ax.plot_date(idx, stock, '-') # Major Axis ax.xaxis.set_major_locator(dates.MonthLocator()) ax.xaxis.set_major_formatter(dates.DateFormatter('\n\n%Y--%B')) # Minor Axis ax.xaxis.set_minor_locator(dates.WeekdayLocator()) ax.xaxis.set_minor_formatter(dates.DateFormatter('%d')) # Grids ax.yaxis.grid(True) ax.xaxis.grid(True) fig.autofmt_xdate() # Auto fixes the overlap! plt.tight_layout() plt.show() # In[33]: fig, ax = plt.subplots(figsize=(10, 8)) ax.plot_date(idx, stock, '-') # Major Axis ax.xaxis.set_major_locator(dates.WeekdayLocator(byweekday=1)) ax.xaxis.set_major_formatter(dates.DateFormatter('%B-%d-%a')) # Grids ax.yaxis.grid(True)
delimiter=',', usecols=(1, 6, 7), unpack=True, dtype='M8[D], f8, f8', converters={1: dmy2ymd}) # 绘制OBV mp.figure('OBV', facecolor='lightgray') mp.title('OBV', fontsize=18) mp.xlabel('Date', fontsize=14) mp.ylabel('Price', fontsize=14) mp.tick_params(labelsize=10) mp.grid(linestyle=':') # 设置主刻度定位器为每周一 ax = mp.gca() ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday=md.MO)) ax.xaxis.set_major_formatter(md.DateFormatter('%Y/%m/%d')) # 把M8[D]转为matplotlib识别的date类型 dates = dates.astype(md.datetime.datetime) # 绘制OBV能量潮 diff_prices = np.diff(closing_prices) sign_prices = np.sign(diff_prices) # 使用piecewise替代sign函数 sign_prices = np.piecewise( diff_prices, [diff_prices < 0, diff_prices == 0, diff_prices > 0], [-1, 0, 1]) up_obvs = volumns[1:][sign_prices >= 0] up_dates = dates[1:][sign_prices >= 0]
def plot_summary(df1, df2): sns.set(style='dark') sns.set() fig, ax = plt.subplots(figsize=(14, 4)) hue_order = ['Accurate', 'Inaccurate'] sns.lineplot(x='window_day', y='ratio', hue='accurate_prediction', hue_order=hue_order, style='accurate_prediction', style_order=hue_order, alpha=0.1, data=df1.toPandas()) sns.lineplot(x='window_day', y='ratio', hue='accurate_prediction', hue_order=hue_order, style='accurate_prediction', style_order=hue_order, legend=False, data=df1.filter(df1.window_day < '2019-07-21').toPandas()) sns.lineplot(x='window_day', y='ratio', hue='accurate_prediction', hue_order=hue_order, style='accurate_prediction', style_order=hue_order, legend=False, alpha=1, data=df2.filter(df2.window_day >= '2019-07-21').toPandas()) plt.yticks(rotation=0) plt.xticks(rotation=0) plt.ylabel('% in population') plt.xlabel('Date') plt.title('Model Monitoring KPI over time') ax.axvline(x='2019-07-10', linewidth=1, linestyle='--', alpha=0.3) ax.axvline(x='2019-07-19', linewidth=1, linestyle='--', alpha=0.3) ax.axvline(x='2019-08-04', linewidth=1, linestyle='--', alpha=0.3) ax.axvline(x='2019-08-12', linewidth=1, linestyle='--', alpha=0.0) ax.text(mdates.date2num(dt.datetime(2019, 7, 1)), 85, '1st model train data', fontsize=9, alpha=0.5) ax.text(mdates.date2num(dt.datetime(2019, 7, 11)), 85, '1st model inference', fontsize=9, alpha=0.5) ax.text(mdates.date2num(dt.datetime(2019, 7, 21)), 85, '2nd model learnt and applied', fontsize=9, alpha=0.5) ax.text(mdates.date2num(dt.datetime(2019, 7, 23)), 70, 'if model not updated', fontsize=9, alpha=0.5) ax.text(mdates.date2num(dt.datetime(2019, 7, 18)), 70, '1st drift', fontsize=9, alpha=0.5, ha='right') ax.text(mdates.date2num(dt.datetime(2019, 8, 4)), 80, '2nd drift', fontsize=9, alpha=0.5, ha='left') ax.legend(bbox_to_anchor=(1.1, 1.05)) rect = patches.Rectangle(xy=(ax.get_xlim()[0], 80), width=ax.get_xlim()[1] - ax.get_xlim()[0], height=20, color='green', alpha=0.1, ec='red') ax.add_patch(rect) ax.xaxis.set_major_locator(mdates.WeekdayLocator()) fig.tight_layout() display(fig) plt.close(fig) return True
def timeseries(self, t, y, save=False, **kwargs): ''' Plots a time series of the data Parameters: - t: list of points in time - assumed to be datetime - y: list of dependent values - length must be that of t - save: whether or not to save the figure, default is False Possible (other) Parameters: - figsize: tuple specifying the size of the figure - default is (16,8) - ylabel (or label): string specifying the ylabel - default is None - ylim: tuple specifying the y-axis limits - default is [min(y),max(y)] - yticks: list specifying the yticks to use - dfault is determined by matplotlib Returns: - fig: the figure handle - ax: the axis handle ''' self.fig_type = 'timeseries' # setting up figure if 'figsize' in kwargs.keys(): fig, ax = plt.subplots(figsize=kwargs['figsize']) else: fig, ax = plt.subplots(figsize=(16, 8)) # plotting data ax.plot(t, y, linewidth=2, color='black') # Setting label ## x - should never be specified and will remain blank since date formats are obvious (imo) ax.set_xlabel('') ## y if 'ylabel' or 'label' in kwargs.keys(): try: ax.set_ylabel(kwargs['ylabel']) except: ax.set_ylabel(kwargs['label']) else: ax.set_ylabel('') # Setting limits ## x if 'xlim' in kwargs.keys(): ax.set_ylim(kwargs['xlim']) else: ax.set_xlim([t[0], t[-1]]) ## y if 'ylim' in kwargs.keys(): ax.set_ylim(kwargs['ylim']) else: ax.set_ylim([np.nanmin(y), np.nanmax(y)]) # Setting ticks ## x - should never be specified ## xticks are determined based on the number of days included in t - breakpoints are shown below: ## - dt(t) < 2 days - hourly (48 ticks) ## - dt(t) < 7 weeks - daily (49 ticks) ## - dt(t) < 1 year - weekly (52 ticks) ## - dt(t) < 4 years - monthly (48 ticks) ## - dt(t) > 4 years - yearly if t[-1] - t[0] < timedelta(days=2): ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y')) ax.xaxis.set_major_locator(mdates.DayLocator()) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%H:%M')) ax.xaxis.set_minor_locator(mdates.HourLocator()) elif t[-1] - t[0] < timedelta(days=49): ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y')) ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%a %d')) ax.xaxis.set_minor_locator(mdates.DayLocator()) elif t[-1] - t[0] < timedelta(days=365): ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%y')) ax.xaxis.set_major_locator(mdates.WeekdayLocator()) elif t[-1] - t[0] < timedelta(days=4 * 365): ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y')) ax.xaxis.set_major_locator(mdates.YearLocator()) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b')) ax.xaxis.set_minor_locator(mdates.MonthLocator()) else: ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y')) ax.xaxis.set_major_locator(mdates.YearLocator()) plt.xticks(rotation=-45, ha='left') plt.setp(ax.xaxis.get_minorticklabels(), rotation=-45, ha='left') ## y if 'yticks' in kwargs.keys(): ax.set_yticks(kwargs['yticks']) else: # default pass # saving figure if save: # default location for Hagen's projects y_var = input('Shorthand for y-variable: ' ) ## user input for variable to identify figure plt.savefig( f'../../reports/figures/{y_var}-{self.fig_type}-{self.study_suffix}.png' ) # return the fig and axis so user can do more unique modifications return fig, ax
converters={1: dmy2ymd}) # 把dates的数据类型改为matplotlib的日期类型 dates = dates.astype(md.datetime.datetime) # 绘制收盘价的折线图 mp.figure('AAPL', facecolor='lightgray') mp.title('AAPL', fontsize=18) mp.xlabel('Date', fontsize=14) mp.ylabel('Price', fontsize=14) mp.grid(linestyle=':') mp.tick_params(labelsize=10) # 设置刻度定位器 ax = mp.gca() maloc = md.WeekdayLocator(byweekday=md.MO) # 以每周周一为主刻度 ax.xaxis.set_major_locator(maloc) # 设置主刻度日期格式 ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d')) miloc = md.DayLocator() # 以每天为次刻度 ax.xaxis.set_minor_locator(miloc) mp.plot(dates, closing_prices, label='Closing Prices', linewidth=2, color='dodgerblue', linestyle='--', alpha=0.7) mp.legend() mp.gcf().autofmt_xdate() # 自动格式化x轴的日期文本
ns.numconf, y2=ns.numdeaths + ns.numrecover, label='Active') ax.plot(ns.date_number, ns.numconf - ns.numdeaths - ns.numrecover, linewidth=2, label='Total Active', color='k') ax.legend(loc=2, ncol=4, bbox_to_anchor=(0.0, 1.1)) ax.set_ylabel('# Cases') mihr = mdates.DayLocator() mhr = mdates.WeekdayLocator(mdates.MO, interval=2) fmt = mdates.DateFormatter('%d %b') ax.xaxis.set_major_locator(mhr) ax.xaxis.set_major_formatter(fmt) ax.xaxis.set_minor_locator(mihr) ax.set_xlim(ns.date_number.min(), ns.date_number.max()) ax.set_ylim(bottom=0) w, h = fig.get_figwidth(), fig.get_figheight() # fig.set_size_inches(w*1.5, h) at = AnchoredText( 'data via https://www.canada.ca/en/public-health/services/diseases/2019-novel-coronavirus-infection.html', loc=2,
def add_state_to_fig(state, fig, spec, row, NUM_STATES, X, reordered_SE_clusters, index_X, reordered_avg_per_clust, load_path=None, save_path=None, separate=False, two_cols=False, configurations=None): SHAPE_PATH, FIGURE_PATH, RAW_DATA_PATH, INCOME_POPULATION_PATH = define_paths( state) almost_sequential_pal = configurations[ 'clustering_palette'] #['#1f78b4','#a6cee3','#fdbf6f','#ff7f00', '#cc78bc'] sns.set_palette(almost_sequential_pal) NUM_COLS = 3 if two_cols: NUM_COLS = 2 SEPARATE_PATH = os.path.abspath( os.path.join(os.getcwd(), '..', 'reports', 'figures', 'Separate_Summary')) # First column if separate: fig = plt.figure(figsize=(5 * 7 / 3, 5 * (6.25 - 0.77) / 4)) ax = fig.add_subplot(111, projection='3d') else: ax = fig.add_subplot( spec[NUM_COLS * row], projection='3d' ) #NUM_STATES, NUM_COLS, NUM_COLS*row + 1, projection = '3d') ax.set_anchor('E') if two_cols: cbar = None else: cbar = 'clustering' _, X_3D_SE = viz_SE(X, reordered_SE_clusters, filename=None, alpha=0.5, cbar=cbar, ax=ax, load_path=load_path, save_path=save_path) if state == 'wa': ax.view_init(30, 200) if state == 'ga': ax.view_init(30, 80) if state == 'tx': ax.view_init(30, 245) if state == 'ca': ax.view_init(30, 80) if state == 'demo': ax.view_init(30, 200) ax.set_xlim(np.array([np.min(X_3D_SE[:, 0]), np.max(X_3D_SE[:, 0])])) ax.set_ylim(np.array([np.min(X_3D_SE[:, 1]), np.max(X_3D_SE[:, 1])])) ax.set_zlim(np.array([np.min(X_3D_SE[:, 2]), np.max(X_3D_SE[:, 2])])) ax.set_xlabel('') ax.set_ylabel('') ax.set_zlabel('') plt.axis('tight') ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 1.0)) ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 1.0)) ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 1.0)) ax.set_xticklabels([]) ax.set_yticklabels([]) ax.set_zticklabels([]) #,rotation=-15, va='center', ha='right') ax.set_xticks([]) ax.set_yticks([]) ax.set_zticks([]) ax.xaxis._axinfo['juggled'] = (0, 0, 1) # ax.dist = 5.5 # ax.yaxis._axinfo['juggled'] = (1,1,1) # ax.zaxis._axinfo['juggled'] = (1,0,0) ax.grid(False) ax.set_title('') # ax.set_ylabel("Median Population", fontname="Arial", fontsize=12) if separate: fig.savefig(os.path.join(FIGURE_PATH, state + '_embedding_col_1.png'), bbox_inches='tight', pad_inches=0, dpi=900) # Second column if separate: fig = plt.figure(figsize=(5 * 7 / 3, 5 * (6.25 - 0.77) / 4)) ax = fig.add_subplot(111) else: ax = fig.add_subplot(spec[NUM_COLS * row + 1]) #NUM_STATES, NUM_COLS, NUM_COLS*row + 2) ax.set_aspect('equal') # ax.set_anchor('C') if state == 'wa': ax.margins(0.2, 0.2) if two_cols: cmap = None else: cmap = 'clust' viz_cluster_map(reordered_SE_clusters, index_X, filename=None, cmap=cmap, ax=ax, title=state, state=state) ax.set_title('') plt.axis('tight') if separate: fig.savefig(os.path.join(FIGURE_PATH, state + '_map_col_2.png'), bbox_inches='tight', pad_inches=0, dpi=900) #Third column if not two_cols: if separate: fig = plt.figure(figsize=(5 * 7 / 3, 5 * (6.25 - 0.77) / 4)) ax = fig.add_subplot(111) else: ax = fig.add_subplot( spec[NUM_COLS * row + 2]) #NUM_STATES, NUM_COLS, NUM_COLS*row + 3) plot_df = reordered_avg_per_clust.T plot_df.index = [ pd.to_datetime(date, format='%Y-%m-%d').date() for date in plot_df.index ] almost_sequential_pal = [ '#1f78b4', '#a6cee3', '#fdbf6f', '#ff7f00', '#cc78bc' ] friendly_cmap = ListedColormap( sns.color_palette(almost_sequential_pal, len(np.unique(reordered_SE_clusters))).as_hex()) plot_df.plot(ax=ax, ylim=[0.1, 0.7], legend=False, cmap=friendly_cmap) ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d')) ax.xaxis.set_minor_locator( mdates.WeekdayLocator(byweekday=MO, interval=1)) ax.tick_params(which='minor', length=0, color='r') ax.tick_params(axis='both', length=10, width=3, which='major') ax.axvline(datetime(2020, 6, 1), color='k', alpha=.3, ls='--', lw=.5) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # Only show ticks on the left and bottom spines ax.yaxis.set_ticks_position('left') ax.xaxis.set_ticks_position('bottom') # ax.xticks(fontsize=11*5) # ax.yticks(fontsize=11*5) ax.tick_params(axis='both', which='major', labelsize=6 * 5) ax.grid(True, 'minor', 'x', ls='--', lw=.5, c='k', alpha=.3) ax.set_xlim([datetime(2020, 2, 19), datetime(2020, 6, 21)]) if separate: fig.savefig(os.path.join(FIGURE_PATH, state + '_time_series_col_3.png'), bbox_inches='tight', pad_inches=0, dpi=900)
def draw(self, df, fname, kind='line', weather=False, rolling=None, highlight=False, title=""): self.df = df self.fname = fname self.kind = kind self.weather = weather self.rolling = rolling self.highlight = highlight if self.rolling is not None: self.df = self.df.rolling(self.rolling).mean() if self.weather == True: self.f, (self.ax, self.wax) = plt.subplots( 2, sharex=True, gridspec_kw={'height_ratios': [4.5, 1]}, figsize=(7, 5)) self.ax = self.set_ax_props() self.wax = self.set_ax_props(self.wax) self.wdf = vw.get_weather_range( self.df.index[0].strftime('%Y-%m'), (self.df.index[-1] - datetime.timedelta(1)).strftime('%Y-%m')) self.wdf = self.wdf.loc[ [x for x in self.wdf.index if x in self.df.index], :] self.wax.bar(self.wdf.index, self.wdf['Total Precipmm'], color=self.fg_color2) self.wax2 = self.wax.twinx() self.wax2 = self.set_ax_props(self.wax2) self.wax2.plot(self.wdf.index, self.wdf['Max Temp'], color=self.fg_color3) self.wax2.set_ylabel('High ($^\circ$C)') self.wax2.yaxis.label.set_color(self.fg_color3) self.wax.set_ylabel('Rain (mm)') self.wax.yaxis.label.set_color(self.fg_color2) self.wax.spines['right'].set_visible(True) self.wax2.spines['right'].set_visible(True) self.wax.tick_params(axis='x', labelrotation=45) self.wax2.tick_params(axis='x', labelrotation=45) if self.kind == 'line': line = self.ax.plot(self.df.index, self.df.values, color=self.fg_color) self.ax.fill_between(self.df.index, 0, self.df.values, color=self.fg_color, alpha=0.8) if self.kind == 'bar': bars = self.ax.bar(self.df.index, self.df.values, color=self.fg_color) # set ticks every week self.ax.xaxis.set_major_locator(mdates.WeekdayLocator()) #set major ticks format self.ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) if self.highlight: [x.set_alpha(0.6) for x in bars[:-1]] if self.kind == 'cumsum': def cumsum(df): df = df.sum(1).cumsum() df.index = df.index.map(lambda x: x.strftime('%H:%M')) df = df.shift() df.iloc[0] = 0 return df for i, df in self.df.groupby(pd.Grouper(freq='d')): df = cumsum(df) self.ax.plot(df.index, df, color='gray', alpha=0.1) self.ax.plot(df.index, df, alpha=1, color=self.fg_color) self.ax.scatter(df.index, df, alpha=1, color=self.fg_color) self.ax.set_ylabel("Daily Cumulative Trips", color=self.ax_color) self.ax.set_xlabel("Hour", color=self.ax_color) year = self.df.index[-1].year date = self.df.index[-1].date().strftime('%Y-%m-%d') gray_line = mlines.Line2D([], [], color=self.ax_color, label="{} so far".format(year)) green_line = mlines.Line2D([], [], color=self.fg_color, marker='.', label="{}".format(date)) self.ax.legend(handles=[green_line, gray_line]) self.ax.set_title(title, x=0.02, y=0.98, horizontalalignment='left') self.f.savefig(self.fname, bbox_inches='tight', facecolor=self.bg_color)
def draw_weekly_chart(self, file, field_list, title_str, plt_width, plt_height, y_unit, save_to_file): """ Draws trent chart :param title_str: title of the chart :param plt_width: width of the canvas :param plt_height: height of the canvas :param y_unit: unit of the y ax :param save_to_file: path to save chart to :return: """ ayer = ArrayMapHelper() mather = MathHelper() ar_history_data = read_csv(file) colors = [(31, 119, 180), (255, 127, 14), (174, 199, 232), (255, 187, 120), (44, 160, 44), (152, 223, 138), (214, 39, 40), (255, 152, 150), (148, 103, 189), (197, 176, 213), (140, 86, 75), (196, 156, 148), (227, 119, 194), (247, 182, 210), (127, 127, 127), (199, 199, 199), (188, 189, 34), (219, 219, 141), (23, 190, 207), (158, 218, 229)] # Scale the RGB values to the [0, 1] range, which is the format matplotlib accepts. for i in range(len(colors)): r, g, b = colors[i] colors[i] = (r / 255., g / 255., b / 255.) plt.figure(figsize=(plt_width, plt_height)) ax = plt.subplot(111) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.spines["right"].set_visible(False) ax.spines["left"].set_visible(False) ax.get_xaxis().tick_bottom() ax.get_yaxis().tick_left() datemin = time.strptime(ar_history_data['Date'].values[0], '%m/%d/%Y') datemin = datetime.date(datemin.tm_year, datemin.tm_mon, datemin.tm_mday) datemin_fix = datemin - datetime.timedelta(3) datemax = time.strptime( ar_history_data['Date'].values[len(ar_history_data['Date'].values) - 1], '%m/%d/%Y') datemax = datetime.date(datemax.tm_year, datemax.tm_mon, datemax.tm_mday) datemax_fix = datemax + datetime.timedelta(7 - datemax.weekday()) ax.set_xlim(datemin_fix, datemax_fix) xus = mdates.MonthLocator() xusFmt = mdates.DateFormatter('%m/%Y') ax.xaxis.set_major_locator(xus) ax.xaxis.set_major_formatter(xusFmt) plt.xticks(fontsize=8) days = mdates.WeekdayLocator() ax.xaxis.set_minor_locator(days) ax.grid(True) plt.tick_params(axis="both", which="both", bottom="on", top="off", labelbottom="on", left="off", right="off", labelleft="on") y_pos_list = [] for rank, column in enumerate(field_list): y_pos_list.append([]) y_pos_list[rank].append(column) y_pos_list[rank].append(ar_history_data[column.replace( "\n", " ")].values[-1]) self.gap_y_position(y_pos_list, 1) mins = [] maxs = [] for rank, column in enumerate(field_list): plt.plot(ar_history_data.Date.values, ar_history_data[column].values, lw=2.5, color=colors[rank]) plt.text(datemax, y_pos_list[rank][1], int(ar_history_data[column].values[-1]), fontsize=8, color=colors[rank]) min_v, min_p, max_v, max_p = ayer.get_array_min_max_index_value( ar_history_data[column].values) mins.append(min_v) maxs.append(max_v) if (min_p != (len(ar_history_data[column].values) - 1)): plt.text(ar_history_data['Date'].values[min_p], min_v - 1, 'min ' + str(int(min_v)), fontsize=8, color=colors[rank]) if (max_p != (len(ar_history_data[column].values) - 1)): plt.text(ar_history_data['Date'].values[max_p], max_v + 1, 'max ' + str(int(max_v)), fontsize=8, color=colors[rank]) y_min, yminminp, yminmax, yminmaxp = ayer.get_array_min_max_index_value( mins) y_max_min, y_maxminp, y_max, y_maxmaxp = ayer.get_array_min_max_index_value( maxs) y_floor = mather.ffloor(int(y_min), y_unit) y_roof = mather.rroof(int(y_max), y_unit) if (len(field_list) > 1): y_roof += y_unit * len(field_list) for rank, column in enumerate(field_list): y_pos = y_roof - y_unit * rank plt.text(datemax_fix - datetime.timedelta( len(ar_history_data[column].values) / 5), y_pos, column, fontsize=8, color=colors[rank]) plt.ylim(y_floor, y_roof + y_unit / 2) plt.yticks( range(y_floor, y_roof + y_unit / 2, y_unit), [str(x) for x in range(y_floor, y_roof + y_unit / 2, y_unit)], fontsize=8) plt.title(title_str, loc='left') plt.savefig(save_to_file, bbox_inches='tight')
'../da_data/aapl.csv', delimiter=',', usecols=(1, 3, 4, 5, 6), dtype='M8[D], f8, f8, f8, f8', unpack=True, converters={1: dmy2ymd}) # 画图 mp.figure('AAPL', facecolor='lightgray') mp.title('AAPL', fontsize=18) mp.grid(linestyle=':') mp.xlabel('Date', fontsize=14) mp.ylabel('Closing Price', fontsize=14) # 设置刻度定位器 import matplotlib.dates as md ax = mp.gca() ax.xaxis.set_major_locator( md.WeekdayLocator(byweekday=md.MO)) ax.xaxis.set_minor_locator(md.DayLocator()) ax.xaxis.set_major_formatter( md.DateFormatter('%Y/%m/%d')) # 把dates转成适合mp绘图的格式 dates = dates.astype(md.datetime.datetime) def profit(open, high, low, close): # 定义买入卖出策略,计算当天收益率 buying = open * 0.99 if (low < buying < high): return (close - buying) / buying return np.nan # 求30天的收益率
#!/usr/bin/env python3 import sys import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import matplotlib.dates as mdates from dateutil.rrule import MO from pandas.plotting import register_matplotlib_converters register_matplotlib_converters() day = mdates.DayLocator() wday = mdates.WeekdayLocator(byweekday=MO) sns.set_context('talk') def plot(df_long, value_var, ylabel, fname): tool_num = df_long['variable'].unique().size pal = sns.color_palette('muted', n_colors=tool_num) g = sns.FacetGrid( df_long, row='group', hue='variable', sharey=False, legend_out=True, height=7, aspect=2, palette=pal) g.map_dataframe( sns.lineplot, x='timestamp', y=value_var) # g.add_legend() g.set_axis_labels('Date', ylabel)
def plot_rt(fig: plt.Figure, target_df: pd.DataFrame, ax: plt.Axes, county_name: str) -> None: above = [1, 0, 0] middle = [1, 1, 1] below = [0, 0, 0] cmap = ListedColormap(np.r_[np.linspace(below, middle, 25), np.linspace(middle, above, 25)]) color_mapped = lambda y: np.clip(y, .5, 1.5) - .5 target_df = target_df.loc[( target_df.index.get_level_values('name') == county_name)] start_dt = pd.to_datetime( target_df['Rt'].index.get_level_values('Date').min()) index = pd.to_datetime(target_df['Rt'].index.get_level_values('Date')) values = target_df['Rt'].values # Plot dots and line ax.plot(index, values, c='k', zorder=1, alpha=.25) ax.scatter(index, values, s=40, lw=.5, c=cmap(color_mapped(values)), edgecolors='k', zorder=2) # Aesthetically, extrapolate credible interval by 1 day either side lowfn = interp1d(date2num(index), target_df['90_CrI_LB'].values, bounds_error=False, fill_value='extrapolate') highfn = interp1d(date2num(index), target_df['90_CrI_UB'].values, bounds_error=False, fill_value='extrapolate') extended = pd.date_range(start=start_dt - pd.Timedelta(days=3), end=index[-1] + pd.Timedelta(days=1)) ax.fill_between(extended, lowfn(date2num(extended)), highfn(date2num(extended)), color='k', alpha=.1, lw=0, zorder=3) ax.axhline(1.0, c='k', lw=1, label='$R_t=1.0$', alpha=.25) ax.set_title(f'{county_name}', loc='left', fontsize=20, fontweight=0, color='#375A97') # Formatting ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b')) ax.xaxis.set_minor_locator(mdates.DayLocator()) ax.yaxis.set_major_locator(ticker.MultipleLocator(1)) ax.yaxis.set_major_formatter(ticker.StrMethodFormatter("{x:.1f}")) ax.yaxis.tick_right() ax.spines['left'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['right'].set_visible(False) ax.margins(0) ax.grid(which='major', axis='y', c='k', alpha=.1, zorder=-2) ax.margins(0) ax.set_ylim(0.0, 5.0) ax.set_xlim( start_dt - pd.Timedelta(days=3), target_df.index.get_level_values('Date')[-1] + pd.Timedelta(days=1)) ax.xaxis.set_major_locator(mdates.WeekdayLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) fig.set_facecolor('w')
def set_date_axes(): ax = plt.gca() formatter = mdates.DateFormatter("%m-%d") ax.xaxis.set_major_formatter(formatter) locator = mdates.WeekdayLocator(byweekday=mdates.MO) ax.xaxis.set_major_locator(locator)
width, height, alpha=1, facecolor=colorrect, edgecolor='black', label=lablabel)) plt.yticks(np.arange(0, 25), np.arange(0, 25)) #plt.xticks(np.arange(1,len(alldates_str)), np.arange(1,len(alldates_str))) plt.xticks(np.arange(1, len(alldates_str) + 1), alldates) handles, labels = currentAxis.get_legend_handles_labels() handle_list, label_list = [], [] for handle, label in zip(handles, labels): if label not in label_list: handle_list.append(handle) label_list.append(label) plt.legend(handle_list, label_list, loc='lower right') #import matplotlib.dates as mdates currentAxis.xaxis.set_major_locator( mdates.WeekdayLocator(byweekday=1, interval=1)) #currentAxis.xaxis.set_major_formatter(mdates.DateFormatter('%d')) #currentAxis.get_xaxis().set_major_locator(mdates.MonthLocator(interval=2)) currentAxis.get_xaxis().set_major_formatter(mdates.DateFormatter('%m')) #fig.autofmt_xdate() plt.gcf().autofmt_xdate() plt.show() #%% Define all reservations
def make_chart_comparison(df_places_to_show, level='countries', scale='log', y='total', mode='static'): week = mdates.WeekdayLocator(interval=2) # every year months = mdates.MonthLocator() # every month month_fmt = mdates.DateFormatter('%b-%d') var_y_suffix = '' if y == 'total' else 'Per100k' label_y_scale = ' (log)' if scale == 'log' else '' label_y_y = '' if y == 'total' else ' per 100k' # get last date from dataframe date = df_places_to_show['Date'].max( ) # datetime.today().strftime('%Y-%m-%d') gap = int(df_places_to_show['gap'].min()) y_lim = df_places_to_show['Total' + var_y_suffix].max() #* 1.2 # Generate the figure **without using pyplot**. fig = Figure(figsize=(8, 5)) ax = fig.subplots() places_to_show = df_places_to_show['Name'].unique()[:2] place_name = 'Country' if level == 'countries' else 'City' df_places_to_show = df_places_to_show.rename(columns={'Name': place_name}) ax.set_title('{} Comparison - COVID-19 Cases vs. Deaths - {}'.format( place_name, date), fontsize=14) sns.scatterplot(x="DayAdj", y='Total' + var_y_suffix, hue=place_name, lw=6, alpha=0.8, data=df_places_to_show, ax=ax) ax.xaxis.set_major_locator(months) ax.xaxis.set_major_formatter(month_fmt) ax.legend(loc='upper left', title="Confirmed cases", frameon=True) ax.set( ylabel='Total confirmed cases{}{}'.format(label_y_y, label_y_scale), xlabel="Date for {} ({}'s data shifted {} days to align death curves)". format(places_to_show[0], places_to_show[1], gap)) ax.set_ylim(0.5, y_lim) if scale == 'log' else ax.set_ylim(-5, y_lim) ax2 = ax.twinx() if scale == 'log': ax.set_yscale('log') ax2.set_yscale('log') ax.yaxis.set_major_formatter( ticker.FuncFormatter(lambda y, _: '{:g}'.format(y))) ax2.yaxis.set_major_formatter( ticker.FuncFormatter(lambda y, _: '{:g}'.format(y))) ax2.grid(False) sns.lineplot(x="DayAdj", y='TotalDeaths' + var_y_suffix, hue=place_name, alpha=0.7, lw=6, ax=ax2, data=df_places_to_show) ax2.legend(loc='lower right', title="Deaths", frameon=True) ax2.set(ylabel='Total deaths{}{}'.format(label_y_y, label_y_scale)) ax2.set_ylim(0.5, y_lim) if scale == 'log' else ax2.set_ylim(-5, y_lim) logo = plt.imread('./static/img/new_logo_site.png') ax.figure.figimage(logo, 95, 70, alpha=.35, zorder=1) fig.tight_layout() # display(fig) # Save it to a temporary buffer. buf = BytesIO() fig.savefig(buf, format="png") buf.seek(0) return buf
def set_xaxis_date_fmt(ax): """ (Borrowed from line_plot) Set the dates on an x-axis nicely, spread over 2 lines If x-axis does not include dates, then has no effect. :param ax: matplotlib axis instance """ xax = ax.get_xaxis() # get the x-axis #Get hold of existing locator and formatter objects major_locator = xax.get_major_locator() major_formatter = xax.get_major_formatter() if not isinstance(major_formatter, pandas.tseries.converter.PandasAutoDateFormatter): #Not using dates, so just return as can't set up dates formats return ax #Use this to figure out the date range over which the xaxis has xaxis_range = major_locator.viewlim_to_dt()[1] - \ major_locator.viewlim_to_dt()[0] #Now use this range to set up the date locations and formatters sensibly. #Minor locator - location of upper datestrings #Minor formatter - format of upper datestrings #Major locator - location of lower datestrings (larger intervals than minor) #Major formatter - format of lower datestrings #Major - used for setting gridlines, so set to smaller intervals than minor #AutoDateLocator - automatically finds appropriate intervals, generally # requesting a minimum of 3 tick locations and a maximum number to ensure # text fits. # interval_multiples is set to ensure these are put at nice locations #MonthLocator etc finds every month (not just nicely intervaled ones) if xaxis_range <= datetime.timedelta(hours=3): #<=3 hour range - display minutes, eg 03:30UTC \n 02/03/2014 major_locator = mpldates.AutoDateLocator(minticks=3, maxticks=6, interval_multiples=True) major_formatter = mpldates.DateFormatter('%H:%M%Z') minor_locator = mpldates.WeekdayLocator() minor_formatter = mpldates.DateFormatter('\n%d/%m/%Y') elif xaxis_range <= datetime.timedelta(days=1): #<=1day range - display hours eg 03UTC \n 02/03/2014 major_locator = mpldates.AutoDateLocator(minticks=3, maxticks=6, interval_multiples=True) #Don't allow 4-hour interval major_locator.intervald[mpldates.HOURLY] = [1, 2, 3, 6, 12] major_formatter = mpldates.DateFormatter('%H%Z') minor_locator = mpldates.WeekdayLocator() minor_formatter = mpldates.DateFormatter('\n%d/%m/%Y') elif xaxis_range <= datetime.timedelta(days=3): #<=3 day range - display every 12 hours and dates eg 12UTC \n 02/03/2014 major_locator = mpldates.HourLocator(byhour=[0, 12]) major_formatter = mpldates.DateFormatter('%H%Z') minor_locator = mpldates.AutoDateLocator(minticks=1, maxticks=4, interval_multiples=True) minor_formatter = mpldates.DateFormatter('\n%d/%m/%Y') elif xaxis_range <= datetime.timedelta(days=14): #<=2 week range - display days and months, eg Sun 02 \n Mar 2014 major_locator = mpldates.AutoDateLocator(minticks=3, maxticks=15, interval_multiples=True) major_formatter = mpldates.DateFormatter('%a %d') minor_locator = mpldates.MonthLocator() minor_formatter = mpldates.DateFormatter('\n%b %Y') elif xaxis_range <= datetime.timedelta(days=62): #<= ~2 month range - display date and month, eg 02 \n Mar 2014 major_locator = mpldates.AutoDateLocator(minticks=3, maxticks=63, interval_multiples=True) major_formatter = mpldates.DateFormatter('%d') minor_locator = mpldates.MonthLocator() minor_formatter = mpldates.DateFormatter('\n%b %Y') elif xaxis_range <= datetime.timedelta(days=750): #<= ~2years range - display month and year, eg Mar \n 2014 major_locator = mpldates.MonthLocator() major_formatter = mpldates.DateFormatter('%b') minor_locator = mpldates.AutoDateLocator(minticks=1, maxticks=3, interval_multiples=True) minor_formatter = mpldates.DateFormatter('\n%Y') else: #> ~ 2years range - display year only eg 2014 major_locator = mpldates.YearLocator() major_formatter = mpldates.DateFormatter('%Y') minor_locator = mpldates.YearLocator() minor_formatter = mpldates.DateFormatter('\n') #Can now set these new locator and formatter objects into the x-axis: xax.set_minor_locator(minor_locator) xax.set_minor_formatter(minor_formatter) xax.set_major_locator(major_locator) xax.set_major_formatter(major_formatter) return ax
def make_chart_response(country, deaths_start, avg_before_deaths, df_to_show): city = df_to_show['City'].iloc[0] df_quar = pd.read_csv(data_dir + 'all_countries_response.csv', parse_dates=['Quarantine']) quarantine = df_quar[df_quar['Country'] == country]['Quarantine'].iloc[0] week = mdates.WeekdayLocator(interval=2) # every year months = mdates.MonthLocator() # every month month_fmt = mdates.DateFormatter('%b-%d') y_lim = df_to_show['TotalDeaths'].max() * 1.2 y2_lim = df_to_show['no2'].max() * 1.8 # Generate the figure **without using pyplot**. fig = Figure(figsize=(10, 5)) ax = fig.subplots() ax.set_title('Assessing quarantine implementation - ' + country, fontsize=16, loc='left') if not pd.isnull(quarantine): ax.axvline(x=quarantine, color='k', linestyle='--', lw=3, label='Official quarantine') ax.scatter(df_to_show['Date'], df_to_show['TotalDeaths'], color='black', alpha=0.7, label='Confirmed deaths') ax.xaxis.set_major_locator(week) ax.xaxis.set_major_formatter(month_fmt) ax.set_yscale('log') ax.yaxis.set_major_formatter( ticker.FuncFormatter(lambda y, _: '{:g}'.format(y))) ax.set_ylim(1, y_lim) ax.set(ylabel='Confirmed deaths') ax2 = ax.twinx() sns.lineplot(x="Date", y='no2', alpha=0.7, lw=6, label='Daily $\mathrm{{NO}}_2$ pollution *', ax=ax2, data=df_to_show) sns.lineplot(x="Date", y=avg_before_deaths, alpha=0.7, lw=6, label='Average pollution **', ax=ax2, data=df_to_show) ax2.grid(False) ax2.xaxis.set_major_locator(week) ax2.xaxis.set_major_formatter(month_fmt) ax2.set_ylim(1, y2_lim) ax2.set(ylabel='$\mathrm{{NO}}_2$ pollution') # ask matplotlib for the plotted objects and their labels lines, labels = ax.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() ax2.legend(lines + lines2, labels + labels2, loc='upper left') annotation = """* Median of $\mathrm{{NO}}_2$ measurements in the most affected city ({city}), 5 days rolling average over time series\n** Average daily $\mathrm{{NO}}_2$ measurements from the begining of 2020 until the first day after {deaths_start} deaths""".format( city=city, deaths_start=deaths_start) ax.annotate(annotation, (0, 0), (0, -30), xycoords='axes fraction', textcoords='offset points', va='top') logo = plt.imread('./static/img/new_logo_site.png') ax.figure.figimage(logo, 100, 110, alpha=.35, zorder=1) fig.tight_layout() # Save it to a temporary buffer. buf = BytesIO() fig.savefig(buf, format="png") buf.seek(0) return buf
def save_plot(): global fig, r_t_range, GAMMA, highest_density_interval # # Column vector of k k = np.arange(0, 70)[:, None] # # Different values of Lambda lambdas = [10, 20, 30, 40] # # Evaluated the Probability Mass Function (remember: poisson is discrete) y = sps.poisson.pmf(k, lambdas) # #fig, ax = plt.subplots() # ax.set(title='Poisson Distribution of Cases\n $p(k|\lambda)$') # plt.plot(k, y, # marker='o', # markersize=3, # lw=0) # plt.legend(title="$\lambda$", labels=lambdas); k = 20 lam = np.linspace(1, 45, 90) likelihood = pd.Series(data=sps.poisson.pmf(k, lam), index=pd.Index(lam, name='$\lambda$'), name='lambda') # likelihood.plot(title=r'Likelihood $P\left(k_t=20|\lambda\right)$'); k = np.array([20, 40, 55, 90]) # We create an array for every possible value of Rt R_T_MAX = 12 r_t_range = np.linspace(0, R_T_MAX, R_T_MAX * 100 + 1) # Gamma is 1/serial interval # https://wwwnc.cdc.gov/eid/article/26/7/20-0282_article # https://www.nejm.org/doi/full/10.1056/NEJMoa2001316 GAMMA = 1 / 7 # Map Rt into lambda so we can substitute it into the equation below # Note that we have N-1 lambdas because on the first day of an outbreak # you do not know what to expect. lam = k[:-1] * np.exp(GAMMA * (r_t_range[:, None] - 1)) # Evaluate the likelihood on each day and normalize sum of each day to 1.0 likelihood_r_t = sps.poisson.pmf(k[1:], lam) likelihood_r_t /= np.sum(likelihood_r_t, axis=0) # Plot it # ax = pd.DataFrame( # data=likelihood_r_t, # index=r_t_range # ).plot( # title='Likelihood of $R_t$ given $k$', # xlim=(0, 10) # ) # ax.legend(labels=k[1:], title='New Cases') # ax.set_xlabel('$R_t$'); posteriors = likelihood_r_t.cumprod(axis=1) posteriors = posteriors / np.sum(posteriors, axis=0) columns = pd.Index(range(1, posteriors.shape[1] + 1), name='Day') posteriors = pd.DataFrame(data=posteriors, index=r_t_range, columns=columns) # ax = posteriors.plot( # title='Posterior $P(R_t|k)$', # xlim=(0, 10) # ) # ax.legend(title='Day') # ax.set_xlabel('$R_t$'); most_likely_values = posteriors.idxmax(axis=0) hdi = highest_density_interval(posteriors) # ax = most_likely_values.plot(marker='o', # label='Most Likely', # title=f'$R_t$ by day', # c='k', # markersize=4) # ax.fill_between(hdi.index, # hdi['Low_90'], # hdi['High_90'], # color='k', # alpha=.1, # lw=0, # label='HDI') # ax.legend(); url = 'https://api.covid19india.org/states_daily.json' req = urllib.request.Request(url) daily_data = json.loads(urllib.request.urlopen(req).read())['states_daily'] states_data = [] non_state_keys = ['date', 'status'] for row in daily_data: this_status = row['status'] # ignore the other two statuses: deceased and recovered if this_status == 'Confirmed': # this_date = datetime.strftime(datetime.strptime(row['date'], '%d-%b-%y'), '%Y-%m-%d') this_date = datetime.strptime(row['date'], '%d-%b-%y').date() for item in row.keys(): if not item in non_state_keys: states_data.append([ state_names[item], this_date, int(row[item]) if row[item] else 0 ]) states_data = sorted(states_data, key=lambda states_data: states_data[0] + states_data[ 1].strftime('%Y-%m-%d')) column_labels = ['state', 'date', 'cases'] states = pd.DataFrame.from_records(states_data, columns=['state', 'date', 'cases'], index=['state', 'date']) states = states.squeeze() states = states.groupby(['state', 'date']).sum().groupby(level=0).cumsum() # if the state has fewer than 30 cases in all OR # there have been fewer than 10 non-zero days FILTERED_REGIONS = set([]) STATES_1000_PLUS = set([]) today = datetime.now().date() for state_name in state_names.values(): cumulative = states.xs(state_name).tail(1).item() daily = states.xs(state_name).diff() if cumulative < 25: FILTERED_REGIONS.add(state_name) print('Removing ' + state_name + ' because there are fewer than 25 cumulative cases') elif len(daily[daily > 0]) < 15: FILTERED_REGIONS.add(state_name) print('Removing ' + state_name + ' because there are fewer than 15 days with non zero cases') else: cases_began = daily[daily > 0].keys()[0].date() days_since_case1 = (today - cases_began).days # z_since_case1 = len(daily[-days_since_case1:][daily==0]) z_7d = len(daily[-7:][daily == 0]) if z_7d > 2: FILTERED_REGIONS.add(state_name) print( 'Removing ' + state_name + ' because there are at least 3 days of zero cases in the last week' ) if cumulative > 1000: STATES_1000_PLUS.add(state_name) state_name = 'Bihar' cases = states.xs(state_name).rename(f"{state_name} cases") original, smoothed = prepare_cases(cases) # original.plot(title=f"{state_name} New Cases per Day", # c='k', # linestyle=':', # alpha=.5, # label='Actual', # legend=True, # figsize=(500 / 72, 300 / 72)) # # ax = smoothed.plot(label='Smoothed', # legend=True) # # ax.get_figure().set_facecolor('w') # Note that we're fixing sigma to a value just for the example posteriors, log_likelihood = get_posteriors(smoothed, sigma=.25) MAX_DATE = posteriors.axes[1][-1].strftime('%Y-%m-%d') MAX_DATE_MINUS_1 = posteriors.axes[1][-2].strftime('%Y-%m-%d') MAX_DATE_MINUS_2 = posteriors.axes[1][-3].strftime('%Y-%m-%d') # ax = posteriors.plot(title=f'{state_name} - Daily Posterior for $R_t$', # legend=False, # lw=1, # c='k', # alpha=.3, # xlim=(0.4, 6)) # ax.plot(posteriors.filter(like=MAX_DATE), c='r') # ax.plot(posteriors.filter(like=MAX_DATE_MINUS_1), c='g') # ax.plot(posteriors.filter(like=MAX_DATE_MINUS_2), c='b') # ax.set_xlabel('$R_t$'); # Note that this takes a while to execute - it's not the most efficient algorithm hdis = highest_density_interval(posteriors, p=.9) most_likely = posteriors.idxmax().rename('ML') # Look into why you shift -1 result = pd.concat([most_likely, hdis], axis=1) fig, ax = plt.subplots(figsize=(600 / 72, 400 / 72)) plot_rt(result, ax, state_name) ax.set_title(f'Real-time $R_t$ for {state_name}') ax.xaxis.set_major_locator(mdates.WeekdayLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) sigmas = np.linspace(1 / 20, 1, 20) targets = ~states.index.get_level_values('state').isin(FILTERED_REGIONS) states_to_process = states.loc[targets] results = {} for state_name, cases in states_to_process.groupby(level='state'): new, smoothed = prepare_cases(cases, cutoff=10) if len(smoothed) == 0: new, smoothed = prepare_cases(cases, cutoff=1) fig, ax = plt.subplots(figsize=(600 / 72, 400 / 72)) ax.plot(new.xs(state_name), c='k', linestyle=':', alpha=.5, label='Actual') ax.plot(smoothed.xs(state_name), label='Smoothed', c='r') leg = ax.legend(ncol=1, loc='upper left', columnspacing=.75) ax.set_title(f'{state_name} New Cases per Day') ax.xaxis.set_major_locator(mdates.WeekdayLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) fig.set_facecolor('w') fig.savefig(current_path + '/static/images/daily_cases/' + state_name + '_daily_cases.png', bbox_inches='tight') plt.cla() result = {} # Holds all posteriors with every given value of sigma result['posteriors'] = [] # Holds the log likelihood across all k for each value of sigma result['log_likelihoods'] = [] try: for sigma in sigmas: posteriors, log_likelihood = get_posteriors(smoothed, sigma=sigma) result['posteriors'].append(posteriors) result['log_likelihoods'].append(log_likelihood) # Store all results keyed off of state name results[state_name] = result except IndexError as e: print('Encountered an error while computing posteriors for ' + state_name) print(str(e)) except ValueError as e: print('Encountered an error while computing posteriors for ' + state_name) print(str(e)) plt.close(fig) # Each index of this array holds the total of the log likelihoods for # the corresponding index of the sigmas array. total_log_likelihoods = np.zeros_like(sigmas) # Loop through each state's results and add the log likelihoods to the running total. for state_name, result in results.items(): # don't use all-India data while aggregating across states if not state_name == 'India': total_log_likelihoods += result['log_likelihoods'] # Select the index with the largest log likelihood total max_likelihood_index = total_log_likelihoods.argmax() # Select the value that has the highest log likelihood sigma = sigmas[max_likelihood_index] # Plot it fig, ax = plt.subplots() ax.set_title(f"Maximum Likelihood value for $\sigma$ = {sigma:.2f}") ax.plot(sigmas, total_log_likelihoods) ax.axvline(sigma, color='k', linestyle=":") final_results = None for state_name, result in results.items(): posteriors = result['posteriors'][max_likelihood_index] try: hdis_90 = highest_density_interval(posteriors, p=.9) hdis_50 = highest_density_interval(posteriors, p=.5) most_likely = posteriors.idxmax().rename('ML') result = pd.concat([most_likely, hdis_90, hdis_50], axis=1) if final_results is None: final_results = result else: final_results = pd.concat([final_results, result]) # clear_output(wait=True) MAX_DATE = max_date(posteriors, -1) MAX_DATE_MINUS_1 = max_date(posteriors, -2) MAX_DATE_MINUS_2 = max_date(posteriors, -3) ax = posteriors.plot( title=f'{state_name} - Daily Posterior for $R_t$', legend=False, lw=1, c='k', alpha=.3, xlim=(0.4, 6)) if MAX_DATE_MINUS_2: ax.plot(posteriors.filter(like=MAX_DATE_MINUS_2), c='b') if MAX_DATE_MINUS_1: ax.plot(posteriors.filter(like=MAX_DATE_MINUS_1), c='g') if MAX_DATE: ax.plot(posteriors.filter(like=MAX_DATE), c='r') ax.set_xlabel('$R_t$') leg = ax.legend(handles=[ Patch(label='yesterday', color='r'), Patch(label='2 days ago', color='g'), Patch(label='3 days ago', color='b'), Patch(label='4+ days ago', color='k', alpha=.3), ], ncol=1, loc='upper right', columnspacing=.75, handletextpad=.5, handlelength=1) fig = ax.get_figure() fig.savefig(current_path + '/static/images/distribution/' + state_name + '_daily_R_t_distribution.png') plt.cla() except ValueError as e: print('Error while processing ' + state_name) print(str(e)) plt.close(fig) ncols = 4 nrows = int(np.ceil(len(results) / ncols)) fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, nrows * 3)) for i, (state_name, result) in enumerate(final_results.groupby('state')): plot_rt(result, axes.flat[i], state_name) fig.tight_layout() fig.set_facecolor('w') #plt.plot() fig.savefig(current_path + '/static/images/plot.png') plt.close(fig)
def ticks_locator(weekInterval): plt.gca().xaxis.set_minor_locator(tk.AutoMinorLocator(7)) plt.gca().xaxis.set_major_formatter(date_format) plt.gca().xaxis.set_major_locator(mdates.WeekdayLocator(interval = weekInterval)) plt.gca().xaxis.set_minor_formatter(tk.NullFormatter())
def _plot_activity_by_date(self, ax): # calculate timeframe timeframe_start_date = self.timeframe_start_date timeframe_end_date = self.timeframe_end_date day_difference = self.subject_relevancy_length - 1 year_difference = timeframe_end_date.year - timeframe_start_date.year month_difference = 12 * year_difference + timeframe_end_date.month - timeframe_start_date.month # convert date strings provided to datetime objects dates = [timeframe_start_date + dt.timedelta(n) for n in range(self.subject_relevancy_length)] messages = [self.messages_over_date[date.isoformat()] for date in dates] is_rolling_average = day_difference > 21 if is_rolling_average: messages = rolling_average(messages, self.ROLL) # plot the chart ax.bar( dates, messages, color=self.BACKGROUND_COLOR, facecolor=self.FOREGROUND_COLOR, width=1 ) # set proper ticker intervals on the X axis accounting for the timeframe year_locator = mdates.YearLocator() month_locator = mdates.MonthLocator() quarter_locator = mdates.MonthLocator(bymonth=[1,4,7,10]) week_locator = mdates.WeekdayLocator(byweekday=mdates.MO) day_locator = mdates.DayLocator() year_formatter = mdates.DateFormatter('%Y') month_formatter = mdates.DateFormatter('%b %Y') day_formatter = mdates.DateFormatter('%-d %b %Y') if month_difference > 48: ax.xaxis.set_major_locator(year_locator) ax.xaxis.set_major_formatter(year_formatter) ax.xaxis.set_minor_locator(quarter_locator) elif month_difference > 24: ax.xaxis.set_major_locator(quarter_locator) ax.xaxis.set_major_formatter(month_formatter) ax.xaxis.set_minor_locator(month_locator) elif day_difference > 70: ax.xaxis.set_major_locator(month_locator) ax.xaxis.set_major_formatter(month_formatter) elif day_difference > 21: ax.xaxis.set_major_locator(week_locator) ax.xaxis.set_major_formatter(day_formatter) ax.xaxis.set_minor_locator(day_locator) else: ax.xaxis.set_major_locator(day_locator) ax.xaxis.set_major_formatter(day_formatter) # set proper X axis formatting half_day = dt.timedelta(hours=12) ax.set_xlim( dt.datetime(timeframe_start_date.year, timeframe_start_date.month, timeframe_start_date.day) - half_day, dt.datetime(timeframe_end_date.year, timeframe_end_date.month, timeframe_end_date.day) + half_day ) for tick in ax.get_xticklabels(): tick.set_rotation(30) tick.set_horizontalalignment('right') # set proper ticker intervals on the Y axis accounting for the maximum number of messages ax.yaxis.set_major_locator(ticker.MaxNLocator(nbins='auto', steps=[10], integer=True)) if max(messages) >= 10: ax.yaxis.set_minor_locator(ticker.AutoMinorLocator(n=10)) # make it look nice ax.set_facecolor(self.BACKGROUND_COLOR) ax.set_xlabel( 'Data (tygodniowa średnia ruchoma)' if is_rolling_average else 'Data', color=self.FOREGROUND_COLOR, fontsize=11, fontweight='bold' ) ax.set_ylabel('Wysłanych wiadomości', color=self.FOREGROUND_COLOR, fontsize=11, fontweight='bold') return ax
# Merge dicts prices_clean = {} for it in instance_types: dummy = {it: {**prices_clean1[it], **prices_clean2[it]}} prices_clean.update(dummy) # Create figure and axis fig, axes = plt.subplots(len(instance_types), 1, figsize=(8, 4 * len(instance_types))) # Silly hack axes = [axes] # To get the weekly ticks right weeks = mdates.WeekdayLocator() weeks_format = mdates.DateFormatter('%Y-%m-%d') # Plot by looping through dict for it, ax in zip(prices_clean.items(), axes): for sr, p in it[1].items(): if sr[-2] == '1': ax.plot(*zip(*p), color=colors[0], label=sr) else: ax.plot(*zip(*p), color=colors[1], label=sr) ax.set_title(f'Differences between regions: {it[0]}', fontstyle='italic') # ax.set_xlabel('date [-]') ax.set_ylabel('price [$/hr]') ax.xaxis.set_major_locator(weeks) ax.xaxis.set_major_formatter(weeks_format)
import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates dfita = pd.read_csv( '../data/pcm-dpc_COVID-19/dati-regioni/dpc-covid19-ita-regioni.csv') dfita['data'] = pd.to_datetime(dfita['data']) pvt = dfita.drop( ['stato', 'codice_regione', 'lat', 'long', 'note_it', 'note_en'], axis=1).groupby(['data']).sum() tss = pvt.diff(axis=0) cols = ['totale_casi', 'dimessi_guariti', 'deceduti'] fig, ax = plt.subplots(figsize=(10, 6)) for c in cols: ax.bar(tss.index, tss[c]) ax.xaxis.set_major_locator(mdates.WeekdayLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) ax.set_title('Italy') ax.set_ylabel('Count') ax.set_xlabel('Date') ax.legend(cols) fig.savefig("../images/italy_new_cases.png")
## Axes tikcks and tick labels @mticker.FuncFormatter def my_ytick_formatter(x, pos): tmp = np.log10(x) if tmp < 3: return str(int(x)) elif tmp < 6: return str(int(x / 1000)) + 'k' else: return str(int(x / 1000000)) + 'M' plt.xticks(rotation=20) #plt.locator_params(axis='y', nbins=3) ax.xaxis.set_major_locator(mdates.WeekdayLocator( byweekday=(mdates.MO))) #DayLocator(bymonthday=range(5,32,10))) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %dth')) ax.yaxis.set_major_formatter(my_ytick_formatter) ## Axes labels ax.set_xlabel(_('Want to help? Complete the survey at \n coronasurveys.org!'), labelpad=30, fontsize=28, fontstyle='italic', fontname='Futura LT') ax.set_ylabel('') ## Title if args.country_code == 'WW':
def format_line_ticks(ax, year_range): year_range = abs(year_range) print "year_range = ", year_range if year_range < 0.0005: # a few hours ax.xaxis.set_major_locator(mdates.HourLocator()) ax.xaxis.set_minor_locator(mdates.MinuteLocator(interval=4)) ax.xaxis.set_major_formatter( mdates.DateFormatter('%Y-%m-%d\n%H:%M:%S')) ax.xaxis.set_minor_formatter(mdates.DateFormatter("%M")) print "ft: 0; %s" % year_range elif year_range < 1.1 / 365: #about a day ax.xaxis.set_major_locator(mdates.HourLocator(interval=5)) ax.xaxis.set_minor_locator(mdates.HourLocator()) ax.xaxis.set_major_formatter( mdates.DateFormatter('%Y-%m-%d\n%H:%M:%S')) ax.xaxis.set_minor_formatter(mdates.DateFormatter("")) print "ft: 0.5; years: %s" % year_range print " days: %s" % (year_range * 365) elif year_range < 3.1 / 365: #about three days ax.xaxis.set_major_locator(mdates.HourLocator(interval=12)) ax.xaxis.set_minor_locator(mdates.HourLocator(interval=4)) ax.xaxis.set_major_formatter( mdates.DateFormatter('%Y-%m-%d\n%H:%M:%S')) ax.xaxis.set_minor_formatter(mdates.DateFormatter("")) print "ft: 0.75; year: %s" % year_range print " days: %s" % (year_range * 365) elif year_range < 7.1 / 365: #about a week ax.xaxis.set_major_locator(mdates.DayLocator(interval=1)) ax.xaxis.set_minor_locator(mdates.HourLocator(interval=6)) ax.xaxis.set_major_formatter( mdates.DateFormatter('%Y-%m-%d\n%H:%M:%S')) ax.xaxis.set_minor_formatter(mdates.DateFormatter("")) print "ft: 0.85; year: %s" % year_range print " days: %s" % (year_range * 365) elif year_range < 0.05: #about half a month ax.xaxis.set_major_locator(mdates.DayLocator(interval=3)) ax.xaxis.set_minor_locator(mdates.DayLocator()) ax.xaxis.set_major_formatter( mdates.DateFormatter('%Y-%m-%d\n%H:%M:%S')) ax.xaxis.set_minor_formatter(mdates.DateFormatter("")) print "ft: 1; %s" % year_range print " days: %s" % (year_range * 365) elif year_range < 0.18: #about two months ax.xaxis.set_major_locator( mdates.WeekdayLocator(byweekday=1, interval=2)) ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=1)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%d %b')) print "ft: 2; yrs: %s" % year_range print " days: %s" % year_range * 365.0 elif year_range < 0.3: #about 3.5 months ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=1)) ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=1)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%d %b')) print "ft: 3; %s" % year_range elif year_range < 0.5: #about 6 months ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_minor_locator(mdates.MonthLocator(bymonthday=15)) ax.xaxis.set_major_formatter(ticker.NullFormatter()) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b %Y')) for tick in ax.xaxis.get_minor_ticks(): tick.tick1line.set_markersize(0) tick.tick2line.set_markersize(0) tick.label1.set_horizontalalignment('center') print "ft: 4; %s" % year_range elif year_range < 1.1: ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_minor_locator(mdates.MonthLocator(bymonthday=15)) ax.xaxis.set_major_formatter(ticker.NullFormatter()) ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b')) for tick in ax.xaxis.get_minor_ticks(): tick.tick1line.set_markersize(0) tick.tick2line.set_markersize(0) tick.label1.set_horizontalalignment('center') print "ft: 5; %s" % year_range elif year_range < 18.3: ax.xaxis.set_major_locator(mdates.YearLocator()) ax.xaxis.set_minor_locator(mdates.YearLocator(month=7)) ax.xaxis.set_major_formatter(ticker.NullFormatter()) ax.xaxis.set_minor_formatter(mdates.DateFormatter("'%y")) for tick in ax.xaxis.get_minor_ticks(): tick.tick1line.set_markersize(0) tick.tick2line.set_markersize(0) tick.label1.set_horizontalalignment('center') print "ft: 6; %s" % year_range else: ax.xaxis.set_major_locator(mdates.YearLocator(10)) ax.xaxis.set_minor_locator(mdates.YearLocator(10)) ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y")) print "ft: 7; %s" % year_range
def _plot_activity_by_date(self, ax): # Convert date strings provided to datetime objects sorted_messages_over_date = sorted( self.messages_over_date.items(), key=lambda date: dt.datetime.strptime(date[0], '%Y-%m-%d') ) dates = [dt.datetime.strptime(date[0], '%Y-%m-%d') for date in sorted_messages_over_date] messages_over_date = [date[1] for date in sorted_messages_over_date] # Plot the chart ax.bar( dates, messages_over_date, color=self.BACKGROUND_COLOR, facecolor=self.FOREGROUND_COLOR, width=1 ) # Set proper ticker intervals on the X axis accounting for the range of time start_date = dates[0] end_date = dates[-1] year_difference = end_date.year - start_date.year month_difference = 12 * year_difference + end_date.month - start_date.month day_difference = (end_date - start_date).days year_locator = mdates.YearLocator() month_locator = mdates.MonthLocator() quarter_locator = mdates.MonthLocator(bymonth=[1,4,7,10]) week_locator = mdates.WeekdayLocator(byweekday=mdates.MO) day_locator = mdates.DayLocator() year_formatter = mdates.DateFormatter('%Y') month_formatter = mdates.DateFormatter('%b %Y') day_formatter = mdates.DateFormatter('%-d %b %Y') if month_difference > 48: ax.xaxis.set_major_locator(year_locator) ax.xaxis.set_major_formatter(year_formatter) ax.xaxis.set_minor_locator(quarter_locator) elif month_difference > 24: ax.xaxis.set_major_locator(quarter_locator) ax.xaxis.set_major_formatter(month_formatter) ax.xaxis.set_minor_locator(month_locator) elif day_difference > 70: ax.xaxis.set_major_locator(month_locator) ax.xaxis.set_major_formatter(month_formatter) elif day_difference > 21: ax.xaxis.set_major_locator(week_locator) ax.xaxis.set_major_formatter(day_formatter) ax.xaxis.set_minor_locator(day_locator) else: ax.xaxis.set_major_locator(day_locator) ax.xaxis.set_major_formatter(day_formatter) for tick in ax.get_xticklabels(): tick.set_rotation(30) tick.set_horizontalalignment('right') half_day = dt.timedelta(hours=12) ax.set_xlim((start_date - half_day, end_date + half_day)) # Set proper ticker intervals on the Y axis accounting for the maximum number of messages ax.yaxis.set_major_locator(ticker.MaxNLocator(nbins='auto', steps=[10], integer=True)) if max(messages_over_date) >= 10: ax.yaxis.set_minor_locator(ticker.AutoMinorLocator(n=10)) # Make it look nice ax.set_facecolor(self.BACKGROUND_COLOR) ax.set_xlabel('Data', color=self.FOREGROUND_COLOR, fontsize=11, fontweight='bold') return ax