def plot_2d(self, x: str, y: str = 'all', plot_type: str = 'line', figsize: Tuple[float, float] = (15, 8), marker: str = 'X', marker_size: int = 50, marker_color: str = 'r', xlim: Tuple[float, float] = None, hspace: float = None) -> None: """Creates a 2D plot of the optimization output for plotting 1 parameter and costs. Args: x: Name of the parameter to plot on the x axis, corresponding to the same name in the generator. y: Can be one of: "cost" The name of another cost variable corresponding to the output from the cost function "all", which creates a subplot for cost plus all other costs plot_type: line or scatter (default line) figsize: Figure size marker: Adds a marker to each point in x, y to show the actual data used for interpolation. You can set this to None to turn markers off. hspace: Vertical space between subplots """ if len(self.experiments) == 0: return if not has_display(): return # Get rid of nans since matplotlib does not like them experiments = [experiment for experiment in self.experiments if experiment.valid()] if xlim: experiments = [experiment for experiment in experiments if experiment.suggestion[x] >= xlim[0] and experiment.suggestion[x] <= xlim[1]] xvalues = [experiment.suggestion[x] for experiment in experiments] yvalues = [] if y == 'all': yvalues.append(('cost', np.array([experiment.cost for experiment in experiments]))) other_cost_keys = experiments[0].other_costs.keys() for key in other_cost_keys: yvalues.append((key, np.array([experiment.other_costs[key] for experiment in experiments]))) elif y == 'cost': yvalues.append(('cost', np.array([experiment.cost for experiment in experiments]))) else: yvalues.append((y, np.array([experiment.other_costs[y] for experiment in experiments]))) xarray = np.array(xvalues) x_sort_indices = np.argsort(xarray) xarray = xarray[x_sort_indices] subplots = [] for tup in yvalues: name = tup[0] yarray = tup[1] yarray = yarray[x_sort_indices] disp = LinePlotAttributes(marker=marker, marker_size=marker_size, marker_color=marker_color) subplots.append( Subplot(data_list=[XYData(name, xarray, yarray, display_attributes=disp)], xlabel=x, ylabel=name, xlim=xlim)) plot = Plot(subplots, figsize=figsize, title='Optimizer 1D Test') plot.draw()
def draw(self, check_data_size: bool = True) -> Optional[Tuple[mpl.figure.Figure, mpl.axes.Axes]]: '''Draw the subplots. Args: check_data_size: If set to True, will not plot if there are > 100K points to avoid locking up your computer for a long time. Default True ''' if not has_display(): print('no display found, cannot plot') return None plot_timestamps = self._get_plot_timestamps() if check_data_size and plot_timestamps is not None and len(plot_timestamps) > 100000: raise Exception(f'trying to plot large data set with {len(plot_timestamps)} points, reduce date range or turn check_data_size flag off') date_formatter = None if plot_timestamps is not None: date_formatter = get_date_formatter(plot_timestamps, self.date_format) height_ratios = [subplot.height_ratio for subplot in self.subplot_list] fig = plt.figure(figsize=self.figsize) gs = gridspec.GridSpec(len(self.subplot_list), 1, height_ratios=height_ratios, hspace=self.hspace) axes = [] for i, subplot in enumerate(self.subplot_list): if subplot.is_3d: ax = plt.subplot(gs[i], projection='3d') else: ax = plt.subplot(gs[i]) axes.append(ax) time_axes = [axes[i] for i, s in enumerate(self.subplot_list) if s.time_plot] if len(time_axes): time_axes[0].get_shared_x_axes().join(*time_axes) for i, subplot in enumerate(self.subplot_list): subplot._draw(axes[i], plot_timestamps, date_formatter) if self.title: axes[0].set_title(self.title) # We may have added new axes in candlestick plot so get list of axes again ax_list = fig.axes for ax in ax_list: if self.show_grid: ax.grid(linestyle='dotted') for ax in ax_list: if ax not in axes: time_axes.append(ax) for ax in time_axes: if self.show_date_gaps and plot_timestamps is not None: _draw_date_gap_lines(ax, plot_timestamps) for ax in ax_list: ax.relim() ax.autoscale_view() return fig, ax_list
def time_distribution(self, frequency: str = '15 minutes', display: bool = True, plot: bool = True, figsize: Optional[Tuple[int, int]] = None) -> pd.DataFrame: ''' Return a dataframe with the time distribution of the bars Args: frequency: The width of each bin (default "15 minutes"). You can use hours or days as well. display: Whether to display the data in addition to returning it. plot: Whether to plot the data in addition to returning it. figsize: If plot is set, optional figure size for the plot (default (20,8)) ''' group_col = None n = int(frequency.split(' ')[0]) freq = frequency.split(' ')[1] df = self.df().reset_index() if freq == 'minutes' or freq == 'mins' or freq == 'min': group_col = [df.date.dt.hour, df.date.dt.minute // n * n] names = ['hour', 'minute'] elif freq == 'hours' or freq == 'hrs' or freq == 'hr': group_col = [df.date.dt.weekday_name, df.date.dt.hour // n * n] names = ['weekday', 'hour'] elif freq == 'weekdays' or freq == 'days' or freq == 'day': group_col = df.date.dt.weekday_name // n * n names = ['weekday'] else: raise Exception(f'unknown time freq: {freq}') count = df.groupby(group_col)['c'].count() tdf = pd.DataFrame({'close_count': count, 'count_pct': count / df.c.count()})[['close_count', 'count_pct']] if 'v' in df.columns: vsum = df.groupby(group_col)['v'].sum() vdf = pd.DataFrame({'volume': vsum, 'volume_pct': vsum / df.v.sum()})[['volume', 'volume_pct']] tdf = pd.concat([vdf, tdf], axis=1) tdf.index.names = names if display: dsp.display(tdf) if plot: if not figsize: figsize = (20, 8) cols = ['close_count', 'volume'] if 'v' in df.columns else ['close_count'] if not has_display(): print('no display found, cannot plot time distribution') return tdf tdf[cols].plot(figsize=figsize, kind='bar', subplots=True, title='Time Distribution') return tdf
def plot_3d(self, x, y, z='all', plot_type='surface', figsize=(15, 15), interpolation='linear', cmap='viridis', marker='X', marker_size=50, marker_color='r', xlim=None, ylim=None, hspace=None): """Creates a 3D plot of the optimization output for plotting 2 parameters and costs. Args: x: Name of the parameter to plot on the x axis, corresponding to the same name in the generator. y: Name of the parameter to plot on the y axis, corresponding to the same name in the generator. z: Can be one of: "cost" The name of another cost variable corresponding to the output from the cost function "all", which creates a subplot for cost plus all other costs plot_type: surface or contour (default surface) figsize: Figure size interpolation: Can be ‘linear’, ‘nearest’ or ‘cubic’ for plotting z points between the ones passed in. See scipy.interpolate.griddata for details cmap: Colormap to use (default viridis). See matplotlib colormap for details marker: Adds a marker to each point in x, y, z to show the actual data used for interpolation. You can set this to None to turn markers off. hspace: Vertical space between subplots """ if len(self.experiments) == 0: print('No experiments found') return if not has_display(): return # Get rid of nans since matplotlib does not like them experiments = [ experiment for experiment in self.experiments if experiment.valid() ] if not len(experiments): print('No valid experiments found') return if xlim: experiments = [ experiment for experiment in experiments if experiment.suggestion[x] >= xlim[0] and experiment.suggestion[x] <= xlim[1] ] if ylim: experiments = [ experiment for experiment in experiments if experiment.suggestion[y] >= ylim[0] and experiment.suggestion[y] <= ylim[1] ] xvalues = [experiment.suggestion[x] for experiment in experiments] yvalues = [experiment.suggestion[y] for experiment in experiments] zvalues = [] if z == 'all': zvalues.append( ('cost', np.array([experiment.cost for experiment in experiments]))) if len(experiments[0].other_costs): other_cost_keys = experiments[0].other_costs.keys() for key in other_cost_keys: zvalues.append((key, np.array([ experiment.other_costs[key] for experiment in experiments ]))) elif z == 'cost': zvalues.append( ('cost', np.array([experiment.cost for experiment in experiments]))) else: zvalues.append((z, np.array([ experiment.other_costs[zname] for experiment in experiments ]))) subplots = [] for tup in zvalues: name = tup[0] zarray = tup[1] if plot_type == 'contour': zlabel = None title = name else: zlabel = name title = None subplots.append( Subplot(data_list=[ XYZData(name, xvalues, yvalues, zarray, plot_type=plot_type, marker=marker, marker_size=marker_size, marker_color=marker_color, interpolation=interpolation, cmap=cmap) ], title=title, xlabel=x, ylabel=y, zlabel=zlabel, xlim=xlim, ylim=ylim)) plot = Plot(subplots, figsize=figsize, title='Optimizer 2D Test', hspace=hspace) plot.draw()