Ejemplo n.º 1
0
class ChartWidget(FigureCanvas):
    def __init__(self,
                 symbol,
                 filepath,
                 width,
                 height,
                 parent,
                 app=None,
                 colorup='g',
                 colordown='r'):

        self.colorup = colorup
        self.colordown = colordown

        self.forecast_window = 30

        self.dataGen = minuteStockDataFeeder(filepath)

        self.chartData = PriceChartData('')

        #for i in range(0, 200):
        #    self.chartData.add(next(self.dataGen))

        df = pd.DataFrame({
            'Date': self.chartData.dates,
            'Time': self.chartData.times,
            'Open': self.chartData.opens,
            'High': self.chartData.highs,
            'Low': self.chartData.lows,
            'Close': self.chartData.closes,
            'Volume': self.chartData.volumes
        })

        self.fig = Figure(figsize=(width, height))
        self.fig.set_tight_layout({"pad": 1.5})

        self.fig.suptitle(symbol)

        self.canvas = FigureCanvas(self.fig)

        gs = gridspec.GridSpec(7, 7)
        gs.update(wspace=0.0, hspace=0.0)  # set the spacing between axes.

        self.tickindex = df.index.values[:-30]
        self.tick_length = len(self.tickindex)

        self.axPrice = self.fig.add_subplot(gs[0:4, :-1])
        self.axPrice.tick_params(axis="y",
                                 direction="in",
                                 left=True,
                                 right=True)
        self.axPrice.get_xaxis().set_visible(False)
        # Specify tick label size
        self.axPrice.tick_params(axis='x', which='major', labelsize=4)
        self.axPrice.tick_params(axis='x', which='minor', labelsize=0)
        self.axPrice.set_xticks(np.arange(0, self.tick_length, 10))
        self.axPrice.set_xticks(np.arange(0, self.tick_length, 1), minor=True)
        self.axPrice.set_xticklabels(
            np.array([
                i - self.tick_length
                for i in np.arange(0, self.tick_length, 10)
            ]))

        major_ticks = np.arange(-10, 110, 10)
        minor_ticks = np.arange(-10, 110, 1)

        self.axPrice.set_yticks(major_ticks)
        self.axPrice.set_yticks(minor_ticks, minor=True)

        self.axPrice.set_ylabel('Price(% of range)', fontsize=8)
        self.axPrice.set_xlim(-170, 0)
        self.axPrice.grid(True)
        self.axPrice.set_alpha(0.)
        self.axLearning = self.fig.add_subplot(gs[0:4, 5:6])
        self.axLearning.set_facecolor('None')

        self.axLearning.set_alpha(0.)
        #self.axLearning.get_yaxis().set_visible(False)
        self.axLearning.set_xticks(np.arange(0, 30, 5))
        self.axLearning.set_xticks(np.arange(0, 30, 1), minor=True)
        self.axLearning.tick_params(axis="x",
                                    direction="in",
                                    top=True,
                                    bottom=False)
        self.axLearning.xaxis.set_ticks_position('top')
        self.axLearning.set_yticks(major_ticks)
        self.axLearning.tick_params(labelleft='off')
        self.axLearning.yaxis.grid(True)
        self.axLearning.set_xticklabels(
            np.array([i - 30 for i in np.arange(0, 30, 5)]))

        self.axForecast = self.fig.add_subplot(gs[0:4, 6:])

        #self.axForecast.get_yaxis().set_visible(False)
        self.axForecast.set_xticks(np.arange(0, 30, 5))
        self.axForecast.set_xticks(np.arange(0, 30, 1), minor=True)
        self.axForecast.tick_params(axis="x",
                                    direction="in",
                                    top=True,
                                    bottom=False)
        self.axForecast.set_yticks(major_ticks)
        self.axForecast.tick_params(labelleft='off')
        self.axForecast.xaxis.set_ticks_position('top')

        self.axForecast.yaxis.grid(True)

        self.axVolume = self.fig.add_subplot(gs[4, :-1], sharex=self.axPrice)

        self.axCash = self.fig.add_subplot(gs[5, :-1])
        self.axCash.get_yaxis().set_visible(False)
        self.axCash.get_xaxis().set_visible(False)

        self.ax5 = self.fig.add_subplot(gs[5, 6:], sharey=self.axPrice)
        self.ax5.get_yaxis().set_visible(False)
        self.ax5.get_xaxis().set_visible(False)

        self.axAction = self.fig.add_subplot(gs[6:, :-1], sharex=self.axPrice)
        self.axAction.get_yaxis().set_visible(False)

        self.ax7 = self.fig.add_subplot(gs[6:, 6:])
        self.ax7.get_yaxis().set_visible(False)
        self.ax7.get_xaxis().set_visible(False)

        self.price_candles = self.candlestick(self.axPrice,
                                              df.Open[:-30],
                                              df.High[:-30],
                                              df.Low[:-30],
                                              df.Close[:-30],
                                              width=1,
                                              colorup=colorup,
                                              colordown=colordown)

        self.axPrice.set_ylabel('Price(% of range)', fontsize=8)

        self.axPrice.grid(True)

        self.volume_bars = self.volume_overlay(self.axVolume,
                                               df.Open[:-30],
                                               df.Close[:-30],
                                               df.Volume[:-30],
                                               colorup=colorup,
                                               colordown=colordown,
                                               width=1)

        self.axVolume.get_xaxis().set_visible(False)

        self.axVolume.yaxis.tick_right()

        self.axVolume.set_yticks(np.arange(0, 10, 2))
        self.axVolume.set_yticks(np.arange(0, 10, 1), minor=True)
        self.axVolume.set_ylabel('Volume', fontsize=8)

        self.axVolume.yaxis.set_label_position('right')
        self.axVolume.grid(True)

        self.axVolume.set_ylim(0, 10)
        self.axVolume.get_xaxis().set_visible(False)

        FigureCanvas.__init__(self, self.fig)
        self.app = app

        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def candlestick(
        self,
        ax,
        opens,
        highs,
        lows,
        closes,
        width=4,
        colorup='g',
        colordown='r',
        alpha=0.75,
    ):

        delta = width / 2.

        barVerts = [((i - delta, open), (i - delta, close), (i + delta, close),
                     (i + delta, open))
                    for i, open, close in zip(range(len(opens)), opens, closes)
                    ]

        downSegments = [((i, low), (i, min(open, close)))
                        for i, low, high, open, close in zip(
                            range(len(lows)), lows, highs, opens, closes)]

        upSegments = [((i, max(open, close)), (i, high))
                      for i, low, high, open, close in zip(
                          range(len(lows)), lows, highs, opens, closes)]

        rangeSegments = upSegments + downSegments

        r, g, b = colorConverter.to_rgb(colorup)
        colorup = r, g, b, alpha
        r, g, b = colorConverter.to_rgb(colordown)
        colordown = r, g, b, alpha
        colord = {
            True: colorup,
            False: colordown,
        }
        colors = [colord[open < close] for open, close in zip(opens, closes)]

        useAA = 0,  # use tuple here
        lw = 0.5,  # and here
        rangeCollection = LineCollection(
            rangeSegments,
            colors=((0, 0, 0, 1), ),
            linewidths=lw,
            antialiaseds=useAA,
        )

        barCollection = PolyCollection(
            barVerts,
            facecolors=colors,
            edgecolors=((0, 0, 0, 1), ),
            antialiaseds=useAA,
            linewidths=lw,
        )

        minx, maxx = 0, len(rangeSegments) / 2
        miny = min([low for low in lows])
        maxy = max([high for high in highs])

        corners = (minx, miny), (maxx, maxy)

        ax.update_datalim(corners)

        # add these last
        rangeCollection.set_alpha(0.4)
        barCollection.set_alpha(0.4)
        ax.collections.clear()

        ax.add_collection(rangeCollection)
        ax.add_collection(barCollection)
        return [rangeCollection, barCollection]

    def volume_overlay(self,
                       ax,
                       opens,
                       closes,
                       volumes,
                       colorup='g',
                       colordown='r',
                       width=4,
                       alpha=1.0):

        colorup = mcolors.to_rgba(colorup, alpha)
        colordown = mcolors.to_rgba(colordown, alpha)
        colord = {True: colorup, False: colordown}
        colors = [
            colord[open < close] for open, close in zip(opens, closes)
            if open != -1 and close != -1
        ]

        delta = width / 2.
        bars = [((i - delta, 0), (i - delta, v), (i + delta, v),
                 (i + delta, 0)) for i, v in enumerate(volumes) if v != -1]

        barCollection = PolyCollection(
            bars,
            facecolors=colors,
            edgecolors=((0, 0, 0, 1), ),
            antialiaseds=(0, ),
            linewidths=(0.5, ),
        )

        barCollection.set_alpha(0.4)
        corners = (0, 0), (len(bars), max(volumes))

        ax.collections.clear()

        ax.add_collection(barCollection)
        ax.update_datalim(corners)
        #ax.autoscale(True)
        #ax.set_aspect('auto')
        #ax.autoscale(False)
        # add these last
        return [barCollection]

    def my_scatter(self, ax, x, y):
        from matplotlib.collections import PathCollection
        from matplotlib.path import Path
        import matplotlib.transforms as mtransforms

        phi = np.linspace(0, 2 * np.pi, 100)
        # Scale, in pixel coordinates
        rad = 2
        x_circle = np.cos(phi) * rad
        y_circle = np.sin(phi) * rad

        verts = np.vstack([x_circle, y_circle]).T
        path = Path(verts, closed=False)
        collection = PathCollection(
            [path],
            facecolor='blue',
            edgecolor='black',
            transOffset=ax.transData,
        )
        collection.set_transform(mtransforms.IdentityTransform())
        ax.add_collection(collection, autolim=True)

        ax.autoscale()

    def millions(self, x):
        'The two args are the value and tick position'
        return '%1.1fM' % (x * 1e-6)

    def thousands(self, x):
        'The two args are the value and tick position'
        return '%1.1fK' % (x * 1e-3)

    def update_chart(self, i=0):
        import time
        tstart = time.time()
        self.chartData.add(next(self.dataGen))

        yh = self.chartData.highs.max()
        yl = self.chartData.lows.min()
        r = 100.0 / (yh - yl)

        vl = self.chartData.volumes.min()
        vh = self.chartData.volumes.max()
        vr = 10.0 / (vh - vl)

        self.df = pd.DataFrame({
            'Date': self.chartData.dates,
            'Time': self.chartData.times,
            'Open': (self.chartData.opens - yl) * r,
            'High': (self.chartData.highs - yl) * r,
            'Low': (self.chartData.lows - yl) * r,
            'Close': (self.chartData.closes - yl) * r,
            'Volume': (self.chartData.volumes - vl) * vr
        })

        ##  Learning zone ####
        self.target_data1 = (
            self.df.High[-2 * self.forecast_window:-self.forecast_window] +
            self.df.Low[-2 * self.forecast_window:-self.forecast_window]) / 2.0

        # ts = self.df.Date[-self.forecast_window:]
        # self.axLearning.lines.clear()
        # self.axLearning.collections.clear()
        #
        # ##### date change line in target zone ######
        #
        # ts2 = ts.ne(ts.shift().bfill()).astype(int)
        # txs = ts2.diff()[ts2.diff() != 0].index.values
        #
        # if len(txs) > 1:
        #     x = txs[1] - self.tick_length
        # else:
        #     x = 0
        #
        # self.tline = self.axForecast.axvline(x=x, linewidth=.5, color='k', alpha=0.5, linestyle='--')

        self.axLearning.lines.clear()
        self.axLearning.collections.clear()

        self.targets1 = self.axLearning.scatter(range(30),
                                                self.target_data1,
                                                s=15,
                                                c="b",
                                                alpha=0.9,
                                                marker="o")

        data = self.target_data1 + self.target_data1 * (
            0.5 - np.random.random(30)) * .2

        self.predhistory = self.axLearning.scatter(range(30),
                                                   data,
                                                   s=15,
                                                   c="k",
                                                   marker="x")

        # self.axForecast.set_xticks(np.arange(0, 30, 5))
        # self.axForecast.set_xticks(np.arange(0, 30, 1), minor=True)
        self.axLearning.set_ylim(-10.0, 110.0)
        self.axLearning.set_xlim(0.0, 30.0)

        #### forecast Targets ############

        self.target_data = (self.df.High[-self.forecast_window:] +
                            self.df.Low[-self.forecast_window:]) / 2.0
        #self.target_data = 100.*np.random.random(30)

        self.target_data = self.target_data + self.target_data * (
            0.5 - np.random.random(30)) * .2

        ts = self.df.Date[-self.forecast_window:]
        self.axForecast.lines.clear()
        self.axForecast.collections.clear()

        ##### date change line in target zone ######

        ts2 = ts.ne(ts.shift().bfill()).astype(int)
        txs = ts2.diff()[ts2.diff() != 0].index.values

        if len(txs) > 1:
            x = txs[1] - self.tick_length
        else:
            x = 0

        self.tline = self.axForecast.axvline(x=x,
                                             linewidth=.5,
                                             color='k',
                                             alpha=0.5,
                                             linestyle='--')

        self.targets = self.axForecast.scatter(range(30),
                                               self.target_data,
                                               s=15,
                                               c="k",
                                               marker="x")
        #self.axForecast.set_xticks(np.arange(0, 30, 5))
        #self.axForecast.set_xticks(np.arange(0, 30, 1), minor=True)
        self.axForecast.set_ylim(-10.0, 110.0)
        self.axForecast.set_xlim(0.0, 30.0)

        ##### axPrice #################
        self.axPrice.texts.clear()
        self.axPrice.lines.clear()
        self.price_candles = self.candlestick(self.axPrice,
                                              self.df.Open[:-30],
                                              self.df.High[:-30],
                                              self.df.Low[:-30],
                                              self.df.Close[:-30],
                                              width=1,
                                              colorup=self.colorup,
                                              colordown=self.colordown)

        self.axPrice.set_ylim(-10.0, 110.0)
        self.axPrice.set_xlim(0.0, 170.0)
        self.price_range = [yh - i * (yh - yl) / 10 for i in range(1, 11)]
        self.price_range = [self.price_range[0] + self.price_range[0] - self.price_range[1]] + self.price_range + \
                           [ self.price_range[9] - self.price_range[0] + self.price_range[1]]

        self.ranges = []
        for i in range(0, 12):
            self.ranges.append(
                self.axPrice.text(self.tick_length - 40, (10 - i) * 10,
                                  '${:1.2f}'.format(self.price_range[i])))

        self.last_price = "Date: {}, Time:{}, Open:{:2.2f}, High:{:2.2f}, Low:{:2.2f}, Close:{:2.2f}, Volume:{}".format(
            self.chartData.dates[-1], self.chartData.times[-1],
            self.chartData.opens[-1], self.chartData.highs[-1],
            self.chartData.lows[-1], self.chartData.closes[-1],
            self.chartData.volumes[-1])
        #print(self.last_price)

        self.text = self.axPrice.text(0.80,
                                      0.95,
                                      self.last_price,
                                      horizontalalignment='right',
                                      verticalalignment='bottom',
                                      transform=self.axPrice.transAxes)

        ##### axVolume #########

        self.axVolume.texts.clear()

        self.volume_bars = self.volume_overlay(self.axVolume,
                                               self.df.Open[:-30],
                                               self.df.Close[:-30],
                                               self.df.Volume[:-30],
                                               colorup=self.colorup,
                                               colordown=self.colordown,
                                               width=1)

        self.vol_range = [(vh - i * (vh - vl) / 5) for i in range(1, 5)]

        self.vol_ranges = []

        for i in range(0, 4):
            self.vol_ranges.append(
                self.axVolume.text(
                    self.tick_length - 10, (4 - i) * 2,
                    '{}'.format(self.thousands(self.vol_range[i]))))

        ##### date change line ######
        s = self.df.Date[:-self.forecast_window]
        s2 = s.ne(s.shift().bfill()).astype(int)
        xs = s2.diff()[s2.diff() != 0].index.values

        if len(xs) > 1:
            x = xs[1]
        else:
            x = 0

        self.line = self.axPrice.axvline(x=x,
                                         linewidth=.5,
                                         color='k',
                                         alpha=0.5,
                                         linestyle='--')

        ####################
        import gc
        gc.collect()
        print('FPS:', 1 / (time.time() - tstart))
        print('Artists:', len(self.fig.findobj()))
        return self.price_candles + self.volume_bars + self.ranges + [
            self.line
        ] + self.vol_ranges + [self.targets] + [self.targets1] + [
            self.predhistory
        ] + [self.tline] + [self.text]

    def refresh(self):
        self.update_chart()
        self.draw()

        self.app.processEvents()
Ejemplo n.º 2
0
def plot_realtime_gammaray(request, object_id) :

    well = Well.objects.get(pk=object_id)
    wltz = pytz.timezone(well.timezone)
    gammas = []    
    times = []

    ragg = ToolMWDRealTime.objects.filter(well=well, type='gammaray').aggregate(Max('time_stamp'))
    hoursago = (ragg['time_stamp__max'] or datetime.utcnow()) - timedelta(hours=1)
    r = ToolMWDRealTime.objects.filter(well=well, type='gammaray', time_stamp__gt=hoursago).order_by('time_stamp')    

    # System goes to 100% memory used if 0-1 points are plotted
    if len(r) < 2 :
        return render_to_response('message.html', {'message': 'No Data to graph'})
    
    [gammas.append(v.value) for v in r]    
    [times.append(v.time_stamp) for v in r]    

    def depth_formatter(time_stamp, arg2) :
        time_stamp = matplotlib.dates.num2date(time_stamp)
        time_stamp = time_stamp.replace(tzinfo=None)
        wlt = pytz.utc.localize(time_stamp).astimezone(wltz).replace(tzinfo=None)
        ftime = wlt.strftime('%H:%M')
        
        try :            
            lower = WITS0.objects.filter(well=well, recid=1, itemid=8, time_stamp__lt = time_stamp ).order_by('-time_stamp')[0]
            higher = WITS0.objects.filter(well=well, recid=1, itemid=8, time_stamp__gt = time_stamp ).order_by('time_stamp')[0]
        except:            
            return '%s / No Dpth' % ftime

        # Linear Interpolation where x = seconds and y = depth    
        x = mktime(time_stamp.timetuple())
        xa = mktime(lower.time_stamp.timetuple())
        xb = mktime(higher.time_stamp.timetuple())

        ya = float(lower.value)
        yb = float(higher.value)
        
        depth = ya + ((x - xa) * (yb - ya))/(xb - xa)
        
        return '%s / %s' % (ftime, str(int(depth)) )

    fig = Figure()
    canvas = FigureCanvas(fig)
    ax = fig.add_axes([0.4, 0.08 ,0.55 ,0.85])
    ax.plot(gammas, times)
    wlt = pytz.utc.localize(ragg['time_stamp__max'] or datetime.utcnow()).astimezone(wltz).replace(tzinfo=None)
    ftime = wlt.strftime('%Y/%m/%d %H:%M')
    title = 'Gamma Ray\n' + ftime
    ax.set_title(title)
    ax.grid(True)
    ax.set_xlabel('Gamma Ray (counts/sec)')
    ax.set_ylabel('Time / Depth (ft)')    
    formatter = dates.DateFormatter('%H:%M') 
    ax.yaxis.set_major_formatter(FuncFormatter(depth_formatter))
    ax.set_ylim(matplotlib.dates.date2num(times[-1]),matplotlib.dates.date2num(times[0]))
    ax.yaxis.set_major_locator( LinearLocator( numticks=10 ) )
    ax.xaxis.set_major_locator( LinearLocator( numticks=5 ) )

    going_down = True
    prev_depth = -999
    for t in times :
        try :            
            lower = WITS0.objects.filter(well=well, recid=1, itemid=8, time_stamp__lt = t ).order_by('-time_stamp')[0]
            higher = WITS0.objects.filter(well=well, recid=1, itemid=8, time_stamp__gt = t ).order_by('time_stamp')[0]
        except:            
            continue

        # Linear Interpolation where x = seconds and y = depth    
        x = mktime(t.timetuple())
        xa = mktime(lower.time_stamp.timetuple())
        xb = mktime(higher.time_stamp.timetuple())

        ya = float(lower.value)
        yb = float(higher.value)
        
        depth = ya + ((x - xa) * (yb - ya))/(xb - xa)
        #print depth, going_down
        if depth < prev_depth :
            if going_down :
                going_down=False
                t1 = t

        if depth >= prev_depth and not going_down :
            going_down=True
            t2 = t                        
            ax.axhspan(matplotlib.dates.date2num(t1), matplotlib.dates.date2num(t2), facecolor='#FF0033', alpha=0.25)

        prev_depth = depth

    if not going_down :
        ax.axhspan(matplotlib.dates.date2num(t1), matplotlib.dates.date2num(times[-1]), facecolor='#FF0033', alpha=0.25)
    
    fontsize=8

    for o in fig.findobj(text.Text) :
        o.set_fontsize(fontsize)
    
    fig.set_size_inches( (3, 5) )
        
    filename = settings.MEDIA_ROOT + '/images/gammaray_rt.png'
    fig.savefig(filename)
         
    return HttpResponseRedirect('/tdsurface/media/images/gammaray_rt.png')