Пример #1
0
    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()
Пример #2
0
    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
Пример #3
0
 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
Пример #4
0
    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()