def _create_weekday_grid(weekday_labels: plt.Subplot, ) -> None: weekday_labels.grid( axis="x", linestyle="-", linewidth=2, color=colors.DAY_GRID_COLOR, alpha=colors.DAY_GRID_ALPHA, zorder=1, )
def plot_price_periods( plot_prices: plt.Subplot, options: ForecastOptions, ) -> None: # set bg color for all graphs for plot in [plot_prices]: plot.set_facecolor(options.bg_color) # Remove all spines for spine in plot.spines.values(): spine.set_visible(False) plot_prices.set_facecolor(options.bg_color) plot_prices.set_ylim(PRICE_Y_LIM) plot_prices.set_xlim([-1, 12]) plot_prices.axes.set_yticks(np.arange(0, 701, 100)) plot_prices.grid( axis="y", linestyle="-", linewidth=0.5, color=colors.PRICE_GRID_COLOR, alpha=colors.PRICE_GRID_ALPHA, ) forecast = options.forecast for pattern in forecast.patterns: for week in pattern.potential_weeks: _create_week_area(plot_prices, week, pattern.pattern) big_pattern = utils.get_pattern(forecast, models.PricePatterns.BIGSPIKE) if big_pattern.chance > 0: _create_pattern_line( plot_prices, spike_breakdown=[x for x in forecast.spikes.big.breakdown], spike_pattern=big_pattern, spike_color=colors.BIG_SPIKE_COLOR, ) small_pattern = utils.get_pattern(forecast, models.PricePatterns.SMALLSPIKE) if small_pattern.chance > 0: _create_pattern_line( plot_prices, spike_breakdown=[x for x in forecast.spikes.small.breakdown], spike_pattern=small_pattern, spike_color=colors.SMALL_SPIKE_COLOR, ) bottom_axis = plot_prices.axes # the x locations for the bars indTods = np.arange(PRICE_PERIOD_COUNT) # Add the time of day labels for each bar bottom_axis.axes.set_xlim(plot_prices.get_xlim()) bottom_axis.axes.set_xticks(indTods) bottom_axis.axes.set_xticklabels(PRICE_TODS) bottom_axis.spines["bottom"].set_position(("axes", -0.01)) # Create weekday labels weekday_labels = bottom_axis.twiny() # We need to make sure the limits match to line up with the bars weekday_labels.set_xlim(plot_prices.get_xlim()) # Place the weekdays between the AM / PM values weekday_labels.set_xticks([0.5, 2.5, 4.5, 6.5, 8.5, 10.5]) # Set the labels weekday_labels.set_xticklabels(PRICE_DAYS) # Move the weekday labels down a littls weekday_labels.spines["bottom"].set_position(("axes", -0.06)) _create_weekday_grid(weekday_labels) # style price axes plot_prices.tick_params( axis="y", labelcolor=colors.PRICE_LABEL_COLOR, labelsize=LABEL_SIZE, labeltop=False, labelbottom=False, labelright=True, labelleft=True, bottom=False, top=False, left=False, ) # style TOD labels bottom_axis.tick_params( axis="x", labelcolor=colors.DAY_LABEL_COLOR, labelsize=LABEL_SIZE, labeltop=False, labelbottom=True, labelright=False, labelleft=False, bottom=False, top=False, left=False, ) # style weekday labels weekday_labels.tick_params( axis="both", labelcolor=colors.DAY_LABEL_COLOR, labelsize=LABEL_SIZE, labelbottom=True, labeltop=False, bottom=False, top=False, left=False, ) # Style tod and day label for current price period current_period = _plot_current_prices(plot_prices, options.ticker) if current_period != -1: bbox = dict( boxstyle="round,pad=0.5", color=colors.DAY_LABEL_COLOR, ) current_tod_label = bottom_axis.xaxis.get_ticklabels()[current_period] current_tod_label.set_color("white") current_tod_label.set_bbox(bbox) _add_cursor(plot_prices, current_period) all_spines = itertools.chain( plot_prices.spines.values(), weekday_labels.spines.values(), ) for spine in all_spines: spine.set_visible(False)
def plot_prices_range( plot: plt.Subplot, ticker: models.Ticker, forecast: models.Forecast, ) -> None: max_pattern = models.PricePatterns.UNKNOWN guaranteed_pattern = models.PricePatterns.UNKNOWN min_pattern = models.PricePatterns.UNKNOWN break_even = ticker.purchase_price plot.axes.set_ylim(PRICE_Y_LIM) plot.axes.set_xlim([0, 4]) bar_anchors = np.arange(4) for i, potential_pattern in enumerate(forecast.patterns): bar_position = bar_anchors[i] if len(potential_pattern.potential_weeks) == 0: continue min_price = potential_pattern.prices_future.min max_price = potential_pattern.prices_future.max pattern_color = colors.PATTERN_COLORS[potential_pattern.pattern] bar_color = colors.color(*pattern_color, alpha=potential_pattern.chance) plot.bar( [bar_position], [max_price - min_price], bottom=min_price, width=0.4, align="edge", color=bar_color, ) if potential_pattern.prices_future.max == forecast.prices_future.max: max_pattern = potential_pattern.pattern if (potential_pattern.prices_future.guaranteed == forecast.prices_future.guaranteed): guaranteed_pattern = potential_pattern.pattern if potential_pattern.prices_future.min == forecast.prices_future.min: min_pattern = potential_pattern.pattern # Create a price grid that matches the price progression plot.grid( axis="y", linestyle="-", linewidth=0.5, color=colors.PRICE_GRID_COLOR, alpha=colors.PRICE_GRID_ALPHA, ) # Create a dotted line line at the breakeven point that matches the price # progression if break_even != 0: _create_price_watermark(plot, "break-even", break_even, va_top=False, pattern=None) # Create a dotted line line at the max profit point _create_price_watermark( plot, "potential", forecast.prices_future.max, va_top=False, pattern=max_pattern, ) # Create a dotted line line at the max guaranteed point _create_price_watermark( plot, "guaranteed", forecast.prices_future.guaranteed, va_top=True, pattern=guaranteed_pattern, ) if forecast.prices_summary.min != forecast.prices_summary.guaranteed: # Create a dotted line line at the min price _create_price_watermark( plot, "minimum", forecast.prices_future.min, va_top=True, pattern=min_pattern, ) # remove axis labels plot.tick_params( axis="both", labeltop=False, labelbottom=False, labelright=False, labelleft=False, top=False, bottom=False, left=False, right=False, ) plot.patch.set_visible(False) for position, spine in plot.spines.items(): spine.set_visible(False)