def pages_queried_timeseries(df, plot_width=600, plot_height=200, rule='1T'):
    ts = df[['url']].resample(rule, how='count').cumsum()
    ts.index = ts.index.tz_convert(tzlocal())
    #Bokeh=0.10.0 misencodes timestamps, so we have to shift by
    ts.index = ts.index.shift(ts.index[0].utcoffset().total_seconds(), freq="S")
    ts = pd.concat([ts[:1], ts]) # prepend 0-value for Line chart compat
    ts.iloc[0]['url'] = 0

    formatter = DatetimeTickFormatter(formats=DATETIME_FORMAT)
    ticker = DatetimeTicker(desired_num_ticks=3)

    source = ColumnDataSource(ts)

    plot = Plot(plot_width=plot_width, plot_height=plot_height,
                x_range=DataRange1d(range_padding=0.1),
                y_range=DataRange1d(start=0),
                **PLOT_FORMATS)
    plot.add_glyph(
        source,
        Line(x='retrieved', y='url', **LINE_FORMATS)
    )
    plot.add_layout(
        DatetimeAxis(axis_label="Date Retrieved", formatter=formatter,
                     ticker=ticker, **AXIS_FORMATS),
        'below')
    plot.add_layout(LinearAxis(axis_label="Total Pages", **AXIS_FORMATS), 'left')

    return plot
Exemplo n.º 2
0
    def plotLineGraph(self, x_list, y_list, value, unit):
        figureTitle = "{} for {}".format(value,
                                         self.dataDate.strftime(DATE_FORMAT))
        logging.debug("Plotting {}".format(figureTitle))
        # output to static HTML file
        output_file("{}Plot.html".format(value))

        x_axis_label = 'Time'
        y_axis_label = '{} ({})'.format(value, unit)

        # create a new plot with a title and axis labels
        p = figure(plot_width=1200,
                   plot_height=600,
                   title=figureTitle,
                   x_axis_label=x_axis_label,
                   y_axis_label=y_axis_label,
                   x_axis_type="datetime")

        # add a line renderer with legend and line thickness
        p.xaxis.ticker = DatetimeTicker(desired_num_ticks=24)
        p.line(x_list, y_list, legend=value, line_width=2)

        p.y_range.start = 0
        if unit == "*C":
            p.y_range.end = 70
        else:
            p.y_range.end = 50

        # show the results
        show(p)
Exemplo n.º 3
0
def getPlot(stock_name,ticked_boxes):
    #lookup stock name; if not found, go to error page
    #presume previous calendar month
    today = datetime.date.today()
    first = today.replace(day=1)
    lastMonthEnd = first - datetime.timedelta(days=1)
    lastMonthStart = lastMonthEnd.replace(day=1)
    sys.stderr.write(','.join(map(str,ticked_boxes)))
    r=requests.get("https://www.quandl.com/api/v3/datatables/WIKI/PRICES.json?ticker=%s&date.gte=%s&date.lte=%s&qopts.columns=date,%s&api_key=yFrECJyVKjZh4z--h7xq"%(stock_name,lastMonthStart.strftime("%y%m%d"),lastMonthEnd.strftime("%y%m%d"),','.join(map(str,ticked_boxes))))
    data=r.json()['datatable']['data']
    columns = list(ticked_boxes)
    columns.insert(0, 'date')
    pddata = pd.DataFrame([d[1:] for d in data], [pd.to_datetime(d[0]) for d in data], columns=ticked_boxes)

    TOOLS = "pan,wheel_zoom,box_zoom,reset,save"
    p = figure(x_axis_type="datetime", tools=TOOLS, plot_width=1000, title=stock_name + " Prices")

    p.xaxis.major_label_orientation = pi / 4
    p.xaxis.axis_label = "Date (month/day)"
    p.xaxis.axis_label_text_font_size = "14pt"
    p.xaxis.major_label_text_font = "12pt"
    p.yaxis.axis_label = "Stock Price (USD)"
    p.yaxis.axis_label_text_font_size = "14pt"
    p.yaxis.major_label_text_font = "12pt"

    if all(feature in ["low","high","close","open"] for feature in ticked_boxes) and len(ticked_boxes)==4:
        #candlestick plot
        mids = (pddata.open + pddata.close) / 2
        spans = abs(pddata.close - pddata.open)

        inc = pddata.close > pddata.open
        dec = pddata.open > pddata.close
        w = 12 * 60 * 60 * 1000

        p.grid.grid_line_alpha = 0.3

        p.segment(pddata.index, pddata.high, pddata.index, pddata.low, color='black')
        p.rect(pddata.index[inc], mids[inc], w, spans[inc], fill_color="#D5E1DD", line_color="black")
        p.rect(pddata.index[dec], mids[dec], w, spans[dec], fill_color="#F2583E", line_color="black")

        script, div = components(p)
        return (div, script)



    p.xaxis.ticker = DatetimeTicker(desired_num_ticks=6)
    #p.xaxis[0].ticker=DaysTicker(interval=3)
    colors=['blue','red','purple','black','green','orange']
    legend={'close':'Closing','open':'Opening','adj_open':'Adjusted Opening','adj_close':'Adjusted Closing','low':'Lowest','high':'Highest'}
    for index,feature in enumerate(ticked_boxes):
        p.line(pddata.index, pddata[feature], line_color=colors[index],line_width=2,legend=legend[feature])
        p.circle(pddata.index, pddata[feature], line_color=colors[index],fill_color=colors[index],size=5)
    script, div=components(p)
    return (div,script)
Exemplo n.º 4
0
def _make_base_plot(dfs, activities, x_range, plot_width=900):
    plot = Plot(
        x_range=x_range,
        y_range=Range1d(0, 11),
        outline_line_color=None,
        background_fill=COLOR_PRIMARY,
        border_fill=COLOR_PRIMARY,
        plot_width=plot_width,
        plot_height=150,
        min_border_top=0,
        toolbar_location=None,
    )

    yticker = BasicTicker(min_interval=3)
    close_ticker = DatetimeTicker(desired_num_ticks=8)
    close_ticks = DatetimeTickFormatter(
        formats={
            'years': ["%b"],
            'months': ["%b"],
            'days': ["%a %d %b"],
            'hours': ["%I%p %d %b"]
        }
    )

    plot.add_layout(LinearAxis(ticker=yticker, **AXIS_PROPERTIES), 'left')
    plot.add_layout(DatetimeAxis(formatter=close_ticks, ticker=close_ticker, **AXIS_PROPERTIES), 'below')
    plot.add_layout(Grid(dimension=1, ticker=yticker, grid_line_alpha=0.3))

    palette = get_palette(activities)

    for i, activity in enumerate(activities):
        source = dfs[activity]
        line = Line(
            line_color=palette[i],
            line_join='round', line_cap='round', line_width=5, line_alpha=0.75,
            x='timestamp', y='cumsum_hrs'
        )
        plot.add_glyph(source, line)

    return plot
Exemplo n.º 5
0
def generate_weather_plot(webcfg,
                          telcfg,
                          date=None,
                          plot_ndays=1,
                          span_hours=24):
    log.info(f"Querying weather limits")
    weather_limits = mongo_query('weather_limits', {}, webcfg)[0]

    if date is None:
        end = datetime.utcnow()
        start = end - timedelta(days=plot_ndays)
    else:
        start = datetime.strptime(date, '%Y%m%dUT')
        end = start + timedelta(days=plot_ndays)

    markersize = 2

    ##-------------------------------------------------------------------------
    ## Temperature Plot
    if webcfg['Weather'].get('plot_temperature', None) is not None:
        log.info('Build temperature plot')
        limit_string = webcfg['Weather'].get(f'plot_temperature_limits',
                                             '25,95')
        ymin, ymax = limit_string.split(',')
        height = webcfg['Weather'].getint('plot_temperature_height', 120)
        plot_temperature = figure(
            width=900,
            height=height,
            x_axis_type="datetime",
            y_range=(float(ymin), float(ymax)),
            x_range=(end - timedelta(hours=span_hours), end),
        )
        plot_values = webcfg['Weather'].get('plot_temperature').split(',')
        query_dict = {'date': {'$gt': start, '$lt': end}}
        colors = ["blue", "black", "black"]
        alphas = [0.8, 0.4, 0.4]
        for i, plot_value in enumerate(plot_values):
            collection, name = plot_value.split(':')
            log.debug(f'  Querying mongo collection {collection}')
            query_result = mongo_query(collection, query_dict, webcfg)

            plot_vals = []
            for d in query_result:
                if name in d.keys():
                    if d.get(f"{name} units", None) == 'C':
                        plot_vals.append((d['date'], d[name] * 1.8 + 32))
                    elif d.get(f"{name} unit", None) == 'C':
                        plot_vals.append((d['date'], d[name] * 1.8 + 32))
                    elif d.get("temperature units", None) == 'C':
                        plot_vals.append((d['date'], d[name] * 1.8 + 32))
                    else:
                        plot_vals.append((d['date'], d[name]))
            plot_vals = np.array(plot_vals)

            if len(plot_vals) == 0:
                log.warning(f'Found 0 data points for {collection}:{name}')

            log.debug(f'  Got {len(plot_vals)} entries')
            if len(plot_vals) > 0:
                plot_temperature.circle(plot_vals[:, 0],
                                        plot_vals[:, 1],
                                        legend_label=f"{plot_value}",
                                        color=colors[i],
                                        fill_alpha=alphas[i],
                                        line_alpha=alphas[i],
                                        size=markersize)
        if len(plot_values) > 1:
            plot_temperature.legend.location = "top_left"
            plot_temperature.legend.margin = 0
            plot_temperature.legend.padding = 0
            plot_temperature.legend.spacing = 0
            plot_temperature.legend.label_text_font_size = '8pt'
        else:
            plot_temperature.legend.visible = False
        plot_temperature.yaxis.axis_label = 'Temp (F)'
        plot_temperature.yaxis.formatter = NumeralTickFormatter(format="0,0")
        plot_temperature.yaxis.ticker = [10, 30, 50, 70, 90, 110]
        plot_temperature.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Humidity Plot
    if webcfg['Weather'].get('plot_humidity', None) is not None:
        log.info('Build humidity plot')
        limit_string = webcfg['Weather'].get(f'plot_humidity_limits', '40,100')
        ymin, ymax = limit_string.split(',')
        height = webcfg['Weather'].getint('plot_humidity_height', 120)
        plot_humidity = figure(
            width=900,
            height=height,
            x_axis_type="datetime",
            y_range=(float(ymin), float(ymax)),
            x_range=(end - timedelta(hours=span_hours), end),
        )
        plot_values = webcfg['Weather'].get('plot_humidity').split(',')
        query_dict = {'date': {'$gt': start, '$lt': end}}
        for i, plot_value in enumerate(plot_values):
            collection, name = plot_value.split(':')
            log.debug(f'  Querying mongo collection {collection}')
            query_result = mongo_query(collection, query_dict, webcfg)
            plot_vals = np.array([(d['date'], d[name]) for d in query_result
                                  if name in d.keys()])
            log.debug(f'  Got {len(plot_vals)} entries')
            if len(plot_vals) == 0:
                log.warning(f'Found 0 data points for {collection}:{name}')
            else:
                if i == 0:
                    where_vhumid = np.where(
                        plot_vals[:, 1] >= weather_limits['very humid'])
                    plot_humidity.circle(plot_vals[where_vhumid][:, 0],
                                         plot_vals[where_vhumid][:, 1],
                                         size=markersize,
                                         color="red",
                                         line_alpha=0.8,
                                         fill_alpha=0.8)

                    where_humid = np.where((plot_vals[:,1] < weather_limits['very humid'])\
                                            & (plot_vals[:,1] >= weather_limits['humid']))
                    plot_humidity.circle(plot_vals[where_humid][:, 0],
                                         plot_vals[where_humid][:, 1],
                                         size=markersize,
                                         color="orange",
                                         line_alpha=0.8,
                                         fill_alpha=0.8)

                    where_nothumid = np.where(
                        plot_vals[:, 1] < weather_limits['humid'])
                    plot_humidity.circle(plot_vals[where_nothumid][:, 0],
                                         plot_vals[where_nothumid][:, 1],
                                         legend_label=f"{plot_value}",
                                         size=markersize,
                                         color="green",
                                         line_alpha=0.8,
                                         fill_alpha=0.8)
                else:
                    plot_humidity.circle(plot_vals[:, 0],
                                         plot_vals[:, 1],
                                         legend_label=f"{plot_value}",
                                         color='black',
                                         line_alpha=0.4,
                                         fill_alpha=0.4,
                                         size=markersize)
        if len(plot_values) > 1:
            plot_humidity.legend.location = "top_left"
            plot_humidity.legend.margin = 0
            plot_humidity.legend.padding = 0
            plot_humidity.legend.spacing = 0
            plot_humidity.legend.label_text_font_size = '8pt'
        else:
            plot_humidity.legend.visible = False
        plot_humidity.yaxis.axis_label = 'Humidity (%)'
        plot_humidity.yaxis.formatter = NumeralTickFormatter(format="0,0")
        plot_humidity.yaxis.ticker = [0, 20, 40, 60, 80, 100]
        plot_humidity.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Cloudiness Plot
    if webcfg['Weather'].get('plot_cloudiness', None) is not None:
        log.info('Build cloudiness plot')
        limit_string = webcfg['Weather'].get(f'plot_cloudiness_limits',
                                             '-50,10')
        ymin, ymax = limit_string.split(',')
        height = webcfg['Weather'].getint('plot_cloudiness_height', 120)
        plot_cloudiness = figure(
            width=900,
            height=height,
            x_axis_type="datetime",
            y_range=(float(ymin), float(ymax)),
            x_range=(end - timedelta(hours=span_hours), end),
        )
        plot_values = webcfg['Weather'].get('plot_cloudiness').split(',')
        query_dict = {'date': {'$gt': start, '$lt': end}}
        for plot_value in plot_values:
            collection, name = plot_value.split(':')
            log.debug(f'  Querying mongo collection {collection}')
            query_result = mongo_query(collection, query_dict, webcfg)
            plot_vals = np.array([(d['date'], d[name]) for d in query_result
                                  if name in d.keys()])
            log.debug(f'  Got {len(plot_vals)} entries')
            if len(plot_vals) > 0:
                where_vcloudy = np.where(
                    plot_vals[:, 1] >= weather_limits['cloudy'])
                plot_cloudiness.circle(plot_vals[where_vcloudy][:, 0],
                                       plot_vals[where_vcloudy][:, 1],
                                       size=markersize,
                                       color="red",
                                       line_alpha=0.8,
                                       fill_alpha=0.8)

                where_cloudy = np.where((plot_vals[:,1] < weather_limits['cloudy'])\
                                        & (plot_vals[:,1] >= weather_limits['clear']))
                plot_cloudiness.circle(plot_vals[where_cloudy][:, 0],
                                       plot_vals[where_cloudy][:, 1],
                                       size=markersize,
                                       color="orange",
                                       line_alpha=0.8,
                                       fill_alpha=0.8)

                where_clear = np.where(
                    plot_vals[:, 1] < weather_limits['clear'])
                plot_cloudiness.circle(plot_vals[where_clear][:, 0],
                                       plot_vals[where_clear][:, 1],
                                       size=markersize,
                                       color="green",
                                       line_alpha=0.8,
                                       fill_alpha=0.8)
        plot_cloudiness.yaxis.axis_label = 'Cloudiness (C)'
        plot_cloudiness.yaxis.formatter = NumeralTickFormatter(format="0,0")
        plot_cloudiness.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Wind Plot
    if webcfg['Weather'].get('plot_wind_speed', None) is not None:
        log.info('Build wind plot')
        limit_string = webcfg['Weather'].get(f'plot_wind_speed_limits',
                                             '-3,85')
        ymin, ymax = limit_string.split(',')
        height = webcfg['Weather'].getint('plot_wind_speed_height', 120)
        plot_wind_speed = figure(
            width=900,
            height=height,
            x_axis_type="datetime",
            y_range=(float(ymin), float(ymax)),
            x_range=(end - timedelta(hours=span_hours), end),
        )
        plot_values = webcfg['Weather'].get('plot_wind_speed').split(',')
        query_dict = {'date': {'$gt': start, '$lt': end}}
        for plot_value in plot_values:
            collection, name = plot_value.split(':')
            log.debug(f'  Querying mongo collection {collection}')
            query_result = mongo_query(collection, query_dict, webcfg)

            plot_vals = []
            for d in query_result:
                if name in d.keys():
                    if d.get(f"{name} units", None) == 'kph':
                        plot_vals.append((d['date'], d[name] * 1.61))
                    elif d.get(f"{name} unit", None) == 'kph':
                        plot_vals.append((d['date'], d[name] * 1.61))
                    elif d.get("wind speed units", None) == 'kph':
                        plot_vals.append((d['date'], d[name] * 1.61))
                    else:
                        plot_vals.append((d['date'], d[name]))
            plot_vals = np.array(plot_vals)

            log.debug(f'  Got {len(plot_vals)} entries')
            if len(plot_vals) > 0:
                where_vwindy = np.where(
                    plot_vals[:, 1] >= weather_limits['very windy'])
                plot_wind_speed.circle(plot_vals[where_vwindy][:, 0],
                                       plot_vals[where_vwindy][:, 1],
                                       size=markersize,
                                       color="red",
                                       line_alpha=0.8,
                                       fill_alpha=0.8)

                where_windy = np.where((plot_vals[:,1] < weather_limits['very windy'])\
                                        & (plot_vals[:,1] >= weather_limits['windy']))
                plot_wind_speed.circle(plot_vals[where_windy][:, 0],
                                       plot_vals[where_windy][:, 1],
                                       size=markersize,
                                       color="orange",
                                       line_alpha=0.8,
                                       fill_alpha=0.8)

                where_calm = np.where(
                    plot_vals[:, 1] < weather_limits['windy'])
                plot_wind_speed.circle(plot_vals[where_calm][:, 0],
                                       plot_vals[where_calm][:, 1],
                                       legend_label=f"{plot_value}",
                                       size=markersize,
                                       color="green",
                                       line_alpha=0.8,
                                       fill_alpha=0.8)

        if webcfg['Weather'].get('plot_wind_gust', None) is not None:
            plot_values = webcfg['Weather'].get('plot_wind_gust').split(',')
            query_dict = {'date': {'$gt': start, '$lt': end}}
            for plot_value in plot_values:
                collection, name = plot_value.split(':')
                log.debug(f'  Querying mongo collection {collection}')
                query_result = mongo_query(collection, query_dict, webcfg)
                plot_vals = np.array([(d['date'], d[name])
                                      for d in query_result
                                      if name in d.keys()])
                log.debug(f'  Got {len(plot_vals)} entries')
                if len(plot_vals) > 0:
                    plot_wind_speed.line(plot_vals[:, 0],
                                         plot_vals[:, 1],
                                         legend_label=f"{plot_value}",
                                         line_width=markersize,
                                         color="black",
                                         line_alpha=0.3)
        if len(plot_values) > 1 or webcfg['Weather'].get(
                'plot_wind_gust', None) is not None:
            plot_wind_speed.legend.location = "top_left"
            plot_wind_speed.legend.margin = 0
            plot_wind_speed.legend.padding = 0
            plot_wind_speed.legend.spacing = 0
            plot_wind_speed.legend.label_text_font_size = '8pt'
        else:
            plot_wind_speed.legend.visible = False
        plot_wind_speed.yaxis.axis_label = 'Wind (mph)'
        plot_wind_speed.yaxis.formatter = NumeralTickFormatter(format="0,0")
        plot_wind_speed.yaxis.ticker = [0, 20, 40, 60, 80]
        plot_wind_speed.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Rain Plot
    if webcfg['Weather'].get('plot_rain', None) is not None:
        log.info('Build rain plot')
        limit_string = webcfg['Weather'].get(f'plot_rain_limits', '500,2800')
        ymin, ymax = limit_string.split(',')
        height = webcfg['Weather'].getint('plot_rain_height', 60)
        plot_rain = figure(
            width=900,
            height=height,
            x_axis_type="datetime",
            y_range=(float(ymin), float(ymax)),
            x_range=(end - timedelta(hours=span_hours), end),
        )
        plot_values = webcfg['Weather'].get('plot_rain').split(',')
        query_dict = {'date': {'$gt': start, '$lt': end}}
        for plot_value in plot_values:
            collection, name = plot_value.split(':')
            log.debug(f'  Querying mongo collection {collection}')
            query_result = mongo_query(collection, query_dict, webcfg)
            plot_vals = np.array([(d['date'], d[name]) for d in query_result
                                  if name in d.keys()])
            log.debug(f'  Got {len(plot_vals)} entries')
            if len(plot_vals) > 0:
                where_dry = np.where(plot_vals[:, 1] >= weather_limits['dry'])
                plot_rain.circle(plot_vals[where_dry][:, 0],
                                 plot_vals[where_dry][:, 1],
                                 size=markersize,
                                 color="green",
                                 line_alpha=0.8,
                                 fill_alpha=0.8)

                where_wet = np.where((plot_vals[:,1] < weather_limits['dry'])\
                                     & (plot_vals[:,1] >= weather_limits['wet']))
                plot_rain.circle(plot_vals[where_wet][:, 0],
                                 plot_vals[where_wet][:, 1],
                                 size=markersize,
                                 color="orange",
                                 line_alpha=0.8,
                                 fill_alpha=0.8)

                where_rain = np.where(plot_vals[:, 1] < weather_limits['wet'])
                plot_rain.circle(plot_vals[where_rain][:, 0],
                                 plot_vals[where_rain][:, 1],
                                 size=markersize,
                                 color="red",
                                 line_alpha=0.8,
                                 fill_alpha=0.8)
        plot_rain.yaxis.axis_label = 'Rain'
        plot_rain.yaxis.formatter = NumeralTickFormatter(format="0.0a")
        plot_rain.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Safe Plot
    if webcfg['Weather'].get('plot_safe', None) is not None:
        log.info('Build safe plot')
        height = webcfg['Weather'].getint('plot_safe_height', 60)
        plot_safe = figure(
            width=900,
            height=height,
            x_axis_type="datetime",
            y_range=(-0.2, 1.2),
            x_range=(end - timedelta(hours=span_hours), end),
        )
        plot_values = webcfg['Weather'].get('plot_safe').split(',')
        query_dict = {'date': {'$gt': start, '$lt': end}}

        for plot_value in plot_values:
            collection, name = plot_value.split(':')
            log.debug(f'  Querying mongo collection {collection}')
            query_result = mongo_query(collection, query_dict, webcfg)
            plot_vals = np.array([(d['date'], d[name]) for d in query_result
                                  if name in d.keys()])
            log.debug(f'  Got {len(plot_vals)} entries')
            if len(plot_vals) > 0:
                where_safe = np.where(plot_vals[:, 1] == True)
                plot_safe.circle(plot_vals[where_safe][:, 0],
                                 plot_vals[where_safe][:, 1],
                                 size=markersize,
                                 color="green",
                                 line_alpha=0.8,
                                 fill_alpha=0.8)
                where_unsafe = np.where(plot_vals[:, 1] != True)
                plot_safe.circle(plot_vals[where_unsafe][:, 0],
                                 plot_vals[where_unsafe][:, 1],
                                 size=markersize,
                                 color="red",
                                 line_alpha=0.8,
                                 fill_alpha=0.8)
        plot_safe.yaxis.axis_label = 'Safe'
        plot_safe.xaxis.axis_label = 'Time (UT)'
        plot_safe.yaxis.formatter = NumeralTickFormatter(format="0,0")
        plot_safe.yaxis.ticker = [0, 1]
        plot_safe.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Dome Status Plot
    ##-------------------------------------------------------------------------
    if webcfg['Weather'].getboolean('plot_dome',
                                    False) is True and telcfg is not None:
        telescope = telcfg['Telescope'].get('name')
        ## Telescope Status Query
        log.info(f"Querying dome status database")
        query_dict = {'date': {'$gt': start, '$lt': end}}
        domestatus = mongo_query(f'{telescope}_dome', query_dict, telcfg)
        log.info(f"  Got {len(domestatus)} data points")
        # 0=open, 1=closed, 2=opening, 3=closing
        shutter_values = {0: 0, 1: 1, 2: 0.25, 3: 0.75, 4: 4}
        for i, d in enumerate(domestatus):
            if d['shutterstatus'] == 4 and i > 0:
                domestatus[i]['open_closed'] = domestatus[i - 1]['open_closed']
            else:
                domestatus[i]['open_closed'] = shutter_values[
                    d['shutterstatus']]

        ## IQMon Query
        log.info(f"Querying IQMon results database")
        query_dict = {
            'telescope': telescope,
            'date': {
                '$gt': start,
                '$lt': end
            }
        }
        iqmon = mongo_query('iqmon', query_dict, telcfg)
        log.info(f"  Got {len(iqmon)} data points")
        iqmon_obj_dates = [d['date'] for d in iqmon if d['imtype'] == 'OBJECT']
        iqmon_obj_alt = [
            d['alt'] / 90 for d in iqmon if d['imtype'] == 'OBJECT'
        ]
        iqmon_cal_dates = [
            d['date'] for d in iqmon if d['imtype'] in ['BIAS', 'DARK']
        ]
        iqmon_cal_alt = [0.5 for d in iqmon if d['imtype'] in ['BIAS', 'DARK']]
        iqmon_flat_dates = [
            d['date'] for d in iqmon
            if d['imtype'] in ['FLAT', 'TWIFLAT', 'DOMEFLAT']
        ]
        iqmon_flat_alt = [
            0.5 for d in iqmon
            if d['imtype'] in ['FLAT', 'TWIFLAT', 'DOMEFLAT']
        ]

        ## Build Telescope Status plot
        log.info('Build Telescope Status plot')
        dome = [s['open_closed'] for s in domestatus]
        dome_date = [s['date'] for s in domestatus]
        height = webcfg['Weather'].getint('plot_dome_height', 60)
        dome_plot = figure(
            width=900,
            height=height,
            x_axis_type="datetime",
            y_range=(-0.2, 1.2),
            x_range=(end - timedelta(hours=span_hours), end),
        )
        #         open_date = [dome_date[i] for i,d in enumerate(dome) if d < 0.5]
        #         open_dome = [d for i,d in enumerate(dome) if d < 0.5]
        #         closed_date = [dome_date[i] for i,d in enumerate(dome) if d >= 0.5]
        #         closed_dome = [d for i,d in enumerate(dome) if d >= 0.5]
        #         dome_plot.line(closed_date, closed_dome, line_width=4, color="black")
        #         dome_plot.line(open_date, open_dome, line_width=4, color="green")

        dome_plot.line(dome_date,
                       dome,
                       line_width=4,
                       color="black",
                       line_alpha=0.8)

        # IQMon Files
        dome_plot.circle(iqmon_obj_dates,
                         iqmon_obj_alt,
                         size=markersize,
                         color="blue",
                         line_alpha=0.8,
                         fill_alpha=0.8)
        dome_plot.circle(iqmon_cal_dates,
                         iqmon_cal_alt,
                         size=markersize,
                         color="black",
                         line_alpha=0.8,
                         fill_alpha=0.8)
        dome_plot.circle(iqmon_flat_dates,
                         iqmon_flat_alt,
                         size=markersize,
                         color="yellow",
                         line_alpha=0.8,
                         fill_alpha=0.8)
        dome_plot.yaxis.axis_label = f'{telcfg["Telescope"].get("name")}'
        dome_plot.xaxis.axis_label = 'Time (UT)'
        dome_plot.yaxis.formatter = NumeralTickFormatter(format="0,0")
        dome_plot.yaxis.ticker = [0, 1]
        dome_plot.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Render
    log.info(f"Overplotting twilights")
    plot_names = [
        'plot_temperature', 'plot_humidity', 'plot_cloudiness',
        'plot_wind_speed', 'plot_rain', 'plot_safe'
    ]
    plot_info_list = []
    for name in plot_names:
        if webcfg['Weather'].get(name, None) is not None:
            log.info(f"  {name}")
            limit_string = webcfg['Weather'].get(f'{name}_limits', None)
            if limit_string is not None:
                ymin, ymax = limit_string.split(',')
            else:
                ymin, ymax = 0, 1
            plot_info_list.append([name, eval(name), float(ymax), float(ymin)])

    plot_column_list = []
    plot_twilights_list = []
    for i, plot_info in enumerate(plot_info_list):
        if webcfg['Weather'].get(plot_info[0], None) is not None:
            if i != 0:
                plot_info[1].x_range = plot_info_list[0][1].x_range
            plot_column_list.append(plot_info[1])
            plot_twilights_list.append(plot_info)
    overplot_twilights(plot_twilights_list,
                       end,
                       webcfg,
                       plot_ndays=plot_ndays,
                       log=log)

    if webcfg['Weather'].getboolean('plot_dome',
                                    False) is True and telcfg is not None:
        plot_column_list.append(dome_plot)

    # Add time log
    plot_column_list[-1].plot_height += 40
    plot_column_list[-1].xaxis.visible = True
    plot_column_list[-1].xaxis.formatter = DatetimeTickFormatter(
        hourmin=['%H:%M'])
    plot_column_list[-1].xaxis.ticker = DatetimeTicker(desired_num_ticks=24)
    plot_column_list[-1].xaxis.axis_label = 'UT Time'

    log.info(f"Rendering bokeh plot for {plot_column_list}")
    script, div = components(column(plot_column_list))

    return script, div
Exemplo n.º 6
0
def bokeh(windfarm='moneen', random=None, outlook=False):
    p("BOKEH outlook " + str(outlook))

    if random:
        username = session.get('username', None)
        if not username or username.lower() != random.lower():
            return redirect(url_for('login'))

    

    """
        Create plot
        
    """

    TOOLS="pan,wheel_zoom,box_zoom,reset"
    #TOOLS="wheel_zoom,box_zoom,reset"

    plot = plt.figure(
        width=800, height=200,
        x_axis_type="datetime",
        #title = "Power (kWh)",
        tools=TOOLS,
        responsive=True
    )


    """
        Get the data for the line chart
        - get df from db TODO: select time limit
        - sort index and take difference
        - get a rollwing window (each reading is 10 seconds so 180*10 = 30 min)
    """
    #p("GET CONN")
    conn = get_db()

    #p("GOT CONN")
    #df = pd.read_sql(con=conn, sql='select * from activepower', index_col='timestamp')
    source = pd.read_sql(con=conn, sql='select * from source', index_col='timestamp')
    


    

    source = plt.ColumnDataSource(data=source)

    line = plot.line(
        x= 'timestamp', y='percent',
        source=source,
        alpha=1, color='#e24a33',
        line_width=2, legend = 'Power (MWh)'
    )

    hline = Span(location=100, dimension='width', line_color='green', line_width=3)

    import time
    now = time.mktime(datetime.datetime.now().timetuple()) * 1000
    vline = Span(location=now, dimension='height', line_color='red', line_width=1, line_dash=[4,4])

    plot.renderers.extend([hline, vline])

    # newline not respected in ticklabels !!!
    plot.xaxis.formatter = DatetimeTickFormatter(days=["%a %d %b"])

    plot.xgrid.band_fill_color = "grey"
    plot.xgrid.band_fill_alpha = 0.05

    #plot.xaxis.axis_label = 'Date'
    plot.xaxis.axis_label_text_font_size = "11pt"
    plot.yaxis.axis_label = '% Power'
    plot.yaxis.axis_label_text_font_size = "11pt"
    plot.yaxis.axis_label_text_font_style = "normal"
    plot.legend.location = "top_left"

    #ts = TimeSeries(rm, x='index', y='values')

    

    hover_line = HoverTool(renderers=[line])
    hover_line.tooltips  = """
        <div>
            <span style="font-size: 15px; font-weight: bold;">@time</span>
        </div>
        <table border="0" cellpadding="10">
            <tr>
                <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">1/2-hourly average: </span></th>
                <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@power MW</span></td>
            </tr>
            <tr>
                <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">1/2-hourly_min:</span></th>
                <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@hourly_min MW</span></td>
            </tr>
            <tr>
                <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">1/2-hourly_max:</span></th>
                <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@hourly_max MW</span></td>
            </tr>
        </table>
    """

    plot.add_tools(hover_line)
    

    col = None

    def add_outages_to_plot(plot, df):

        df['midpoint'] = df.startdate + (df.finishdate-df.startdate)/2
        df['midpoint'] = df.midpoint.apply(lambda x: np.datetime64(x).astype('datetime64[ms]').view(np.int64))
        df['duration'] = df.finishdate-df.startdate
        df['height'] = 100 - (df.availability)
        df['width'] = df.duration.apply(lambda x: x.total_seconds()*1000)
        df['start'] = df.startdate.dt.strftime("%A, %e %B %H:%M")
        df['finish'] = df.finishdate.dt.strftime("%A, %e %B %H:%M")
        df['y'] = 100 -(df['height']/2)

        rect = plot.rect(

                x = 'midpoint',
                y = 'y',
                height = 'height',
                width = 'width',
                color = 'purple',
                source=df
        )

        return rect

    def create_outages_datatable(df):

        from bokeh.models import ColumnDataSource
        from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
        source = ColumnDataSource(df)
        columns = [
            TableColumn(field="start", title="Start"),
            TableColumn(field="finish", title="Finish"),
            TableColumn(field="availability", title="% Available"),
            TableColumn(field="timestamp", title="Updated At"),
        ]

        table_height = len(df) * 24 + 30
        data_table = DataTable(source=source, columns=columns,row_headers=True, width=770, height=table_height,
          sizing_mode='scale_both' )

        return source, data_table

    plot_div, dt_div, bokeh_script = '','',''

    if random:
        random = random.lower()
        
        conn = get_db()
        cursor = conn.cursor()
        q = """select * from appointments where random = '{r}'""".format(r=random)


        df = pd.read_sql(con=conn, sql=q)

        if not df.empty:

            rect = add_outages_to_plot(plot,df)

            hover_rect = HoverTool(renderers=[rect])
            hover_rect.tooltips  = """
                <div>
                    <span style="font-size: 15px; font-weight: bold;">@date</span>
                </div><a href="http://www.bbc.co.uk">:
                <table border="0" cellpadding="10">
                    <tr>
                        <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">Start: </span></th>
                        <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@start MWh</span></td>
                    </tr>
                    <tr>
                        <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">End:</span></th>
                        <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@finish</span></td>
                    </tr>
                    <tr>
                        <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">% Available:</span></th>
                        <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@availability</span></td>
                    </tr>
                </table>
                </a>
            """

            plot.add_tools(hover_rect)

            
            
            url = "/appointment/{windfarm}/{random}/edit/@start".format(windfarm=windfarm,random=random)
            taptool = plot.select(type=TapTool)
            #taptool = rect.select(type=TapTool)

            alert_js = """
           
                console.log("PARENT: " + showDiv(source.data['jobnumber'][source.selected["1d"].indices]))

               
            """

            source, data_table   = create_outages_datatable(df)
            source.callback = CustomJS(
                args = dict(source=source),
                code = alert_js
            )

            from bokeh.layouts import column
            col = column(plot, data_table)
            bokeh_script, comps  = components({"plot":plot,"dt":data_table})
            plot_div, dt_div = comps['plot'], comps['dt']
            
            
    
    if not col:
        col = plot
        bokeh_script, plot_div  = components(plot)

    plot.xaxis[0].ticker = DatetimeTicker()

    if not outlook:
        template = "l2.html"
    else:
        template = "outlook.html"

    p("TEMPLATE BEING USED: " + template)
    return render_template(template, windfarm=windfarm, random=random, 
        plot_div=plot_div, dt_div=dt_div, bs=bokeh_script)
Exemplo n.º 7
0
def generate_iqmon_plot(cfg, date=None, plot_ndays=1, span_hours=24):
    telescope = cfg['Telescope'].get('name')

    if date is None:
        end = datetime.utcnow()
        start = end - timedelta(days=plot_ndays)
    else:
        start = datetime.strptime(date, '%Y%m%dUT')
        end = start + timedelta(days=plot_ndays)

    ##-------------------------------------------------------------------------
    ## IQMon Query
    log.info(f"Querying IQMon results database")
    query_dict = {'telescope': telescope, 'date': {'$gt': start, '$lt': end}}
    query_result = mongo_query('iqmon', query_dict, cfg)
    iqmon = [d for d in query_result]
    log.info(f"  Got {len(iqmon)} data points")

    dates_fwhm = [d['date'] for d in iqmon if 'fwhm' in d.keys()]
    fwhm = [d['fwhm'] for d in iqmon if 'fwhm' in d.keys()]
    dates_elip = [d['date'] for d in iqmon if 'ellipticity' in d.keys()]
    elip = [d['ellipticity'] for d in iqmon if 'ellipticity' in d.keys()]

    markersize = 2

    ##-------------------------------------------------------------------------
    ## FWHM Plot
    log.info('Build FWHM plot')
    fwhm_plot = figure(
        width=900,
        height=200,
        x_axis_type="datetime",
        y_range=(0, 10),
        x_range=(end - timedelta(hours=span_hours), end),
    )
    fwhm_plot.circle(dates_fwhm,
                     fwhm,
                     size=markersize,
                     color="blue",
                     alpha=0.8)
    fwhm_plot.yaxis.axis_label = 'FWHM (pix)'
    fwhm_plot.yaxis.formatter = NumeralTickFormatter(format="0,0")
    fwhm_plot.xaxis.visible = False

    ##-------------------------------------------------------------------------
    ## Ellipticity Plot
    log.info('Build ellipticity plot')
    ellipticity_plot = figure(
        width=900,
        height=200,
        x_axis_type="datetime",
        y_range=(1, 2),
        x_range=fwhm_plot.x_range,
    )
    ellipticity_plot.circle(dates_elip,
                            elip,
                            size=markersize,
                            color="blue",
                            alpha=0.8)
    ellipticity_plot.yaxis.axis_label = 'ellipticity'
    ellipticity_plot.yaxis.formatter = NumeralTickFormatter(format="0.0")
    ellipticity_plot.xaxis.visible = True

    ellipticity_plot.xaxis.formatter = DatetimeTickFormatter(hourmin=['%H:%M'])
    ellipticity_plot.xaxis.ticker = DatetimeTicker(desired_num_ticks=24)
    ellipticity_plot.xaxis.axis_label = 'UT Time'

    ##-------------------------------------------------------------------------
    ## Render
    log.info(f"Rendering bokeh plot")
    script, div = components(column(
        fwhm_plot,
        ellipticity_plot,
    ))

    return script, div
Exemplo n.º 8
0
def create_daily_res_plot(res_forecast, load_forecast):
    """
    Graph the res injection forecast.

    Arguments:
        res_forecast (list): list of renewable energy injection forecast
        load_forecast (list): list of load forecast
    """
    # Datetime range
    time_of_day = []

    # Create x-axis
    # beginning of day
    today = datetime.datetime.today()
    beginning_of_day = datetime.datetime(year=today.year,
                                         month=today.month,
                                         day=today.day)

    for i in range(len(res_forecast)):
        time_of_day.append(beginning_of_day +
                           datetime.timedelta(minutes=i * 30))

    # Compute 75 percentile
    percentile = np.percentile(res_forecast, 75)

    # Initialize dictionaries
    normal_dict = {'x': [], 'y': [], 'percentage': []}
    peak_dict = {'x': [], 'y': [], 'percentage': []}

    for i in range(len(res_forecast)):
        if res_forecast[i] >= percentile:
            peak_dict['x'].append(time_of_day[i])
            peak_dict['y'].append(res_forecast[i])
            peak_dict['percentage'].append(
                percentage_of(res_forecast[i], load_forecast[i]))
        else:
            normal_dict['x'].append(time_of_day[i])
            normal_dict['y'].append(res_forecast[i])
            normal_dict['percentage'].append(
                percentage_of(res_forecast[i], load_forecast[i]))

    # Hover tool to properly display time of day and value on hover
    hover = HoverTool(
        tooltips=[("Time of day", "@x{%H:%M}"), ("Forecast Value", "@y MWh"),
                  ("Percentage of Daily Load", "@percentage{1.11} %")],
        formatters={'@x': 'datetime'},
    )

    # Create the figure
    plot = figure(
        x_axis_label="Time of Day",
        y_axis_label="Megawatts Per Hour",
        x_axis_type='datetime',
        sizing_mode="stretch_width",
        tools=[
            hover,
            BoxZoomTool(),
            ResetTool(),
            LassoSelectTool(),
            WheelZoomTool(),
            PanTool(),
            SaveTool()
        ],
    )

    plot.xaxis.formatter = DatetimeTickFormatter(
        minutes=["%H:%M"],
        hours=["%H:%M"],
    )

    # Set x-range and y-range
    plot.y_range = Range1d(min(res_forecast) - 200, max(res_forecast) + 100)
    plot.x_range = Range1d(time_of_day[0] - datetime.timedelta(minutes=5),
                           time_of_day[-1] + datetime.timedelta(minutes=5))

    # Set a grid
    plot.grid.minor_grid_line_color = '#eeeeee'

    # Set the font and style of labels
    plot.axis.axis_label_text_font = "raleway"
    plot.axis.axis_label_text_font_style = "normal"

    # Set the font of ticks on the axis
    plot.axis.major_label_text_font = "raleway"

    # Set the desired ticks
    plot.xaxis.ticker = DatetimeTicker(desired_num_ticks=24)
    plot.yaxis.ticker = AdaptiveTicker(desired_num_ticks=20)

    # Add a line plot
    plot.line(time_of_day,
              res_forecast,
              line_alpha=0.2,
              color="#264b01",
              line_width=1.5)

    # Add two circle plots one for the normal values and one for those that
    # are at or above the 75-percentile
    plot.circle('x', 'y', source=normal_dict, size=8, color="#264b01")
    plot.circle('x', 'y', source=peak_dict, size=15, color="#264b01")

    return components(plot)
Exemplo n.º 9
0
def plot_odds_goals(db_, team_home, team_away):
    """
    Retrieves match from db, creates a dataframe of odds and plots odds over time.

    todo: creating the dataframe should be done in a different function
    """

    # Retrieve match from database
    m = db_.matches.find_one({'team_home': team_home, 'team_away': team_away})
    if m is None:
        return None

    df = utils.create_odds_df(m)

    # Filter over the following bookies
    # todo: get them from a config file
    bookies_to_plot = ['Bet 365',
                       'Sky Bet',
                       'Ladbrokes',
                       "William Hill",
                       "Marathon Bet",
                       "Betfair Sportsbook",
                       "SunBets",
                       "Paddy Power",
                       "Unibet",
                       "Coral",
                       "Betfred",
                       "Bet Victor"]
    filters = [(df.bookie == "Bet 365") | (df.bookie == "Bet365"),
          (df.bookie == "Sky Bet") | (df.bookie == "Skybet"),
          (df.bookie == "Ladbrokes"),
          (df.bookie == "William Hill"),
          (df.bookie == "Marathon Bet"),
          (df.bookie == "Betfair Sportsbook"),
          (df.bookie == "SunBets"),
          (df.bookie == "Paddy Power"),
          (df.bookie == "Unibet"),
          (df.bookie == "Coral"),
          (df.bookie == "Betfred"),
          (df.bookie == "Bet Victor")]

    colors = itertools.cycle(palette)

    # output to static HTML file
    title = "%s | %s - %s | %s" % (str(m['match_datetime']), m['team_home'], m['team_away'], m['result']['score'])
    output_file("templates/goals_timeseries.html", title="Odds %s - %s" %(team_home, team_away))

    # create a new plot with a title and axis labels
    f1 = figure(title="Over 2.5 | %s" % title, x_axis_type="datetime", x_axis_label='Time', y_axis_label='Odd', plot_width=900, plot_height=350)
    f2 = figure(title="Under 2.5 | %s" % title, x_axis_type="datetime", x_axis_label='Time', y_axis_label='Odd', plot_width=900, plot_height=350)

    for filter_, bookie, color in zip(filters, bookies_to_plot, colors):
        source = ColumnDataSource(df[filter_])
        f1.line('datetime', 'over2_5', legend=bookie, color=color, line_width=2, source=source, alpha=0.8)
        f1.circle('datetime', 'over2_5', color=color, source=source)
        f2.line('datetime', 'under2_5', legend=bookie, color=color, line_width=2, source=source, alpha=0.8)
        f2.circle('datetime', 'under2_5',color=color, source=source)

    f1.xaxis.ticker = DatetimeTicker(desired_num_ticks=15)
    f2.xaxis.ticker = DatetimeTicker(desired_num_ticks=15)
    f1.legend.location = "top_left"
    f2.legend.location = "top_left"
    save(column(f1,f2))
    return True
Exemplo n.º 10
0
def bokehs(windfarm='moneen', user='', outlook=False):
    p("BOKEH outlook " + str(outlook))

    username = session.get('username', None)
    username = session.get('username', '')
    if not username or username.lower() != user.lower():
        #return redirect(url_for('login'))
        pass
    """
        Create plot
        
    """

    TOOLS = "pan,wheel_zoom,box_zoom,reset"
    #TOOLS="wheel_zoom,box_zoom,reset"

    plot = plt.figure(
        width=800,
        height=200,
        x_axis_type="datetime",
        #title = "Power (kWh)",
        tools=TOOLS,
        responsive=True)

    plot = plt.figure(
        width=600,
        height=200,
        x_axis_type="datetime",
        #title = "Power (kWh)",
        tools=TOOLS,
        responsive=True,
        toolbar_location="above")

    plot.xaxis[0].ticker = DatetimeTicker()
    """
        Get the data for the line chart
        - get df from db TODO: select time limit
        - sort index and take difference
        - get a rollwing window (each reading is 10 seconds so 180*10 = 30 min)
    """
    #p("GET CONN")
    conn = get_db()

    #p("GOT CONN")
    #df = pd.read_sql(con=conn, sql='select * from activepower', index_col='timestamp')
    power_df = pd.read_sql(con=conn,
                           sql='select * from source order by timestamp')
    power_df['setpoint'] = 100

    #hline = Span(location=100, dimension='width', line_color='green', line_width=3)

    import time
    now = time.mktime(datetime.datetime.now().timetuple()) * 1000
    vline = Span(location=now,
                 dimension='height',
                 line_color='red',
                 line_width=1,
                 line_dash=[4, 4])

    plot.renderers.extend([vline])

    # newline not respected in ticklabels !!!
    plot.xaxis.formatter = DatetimeTickFormatter(days=["%a %d %b"])
    p(dir(plot.xaxis))
    plot.xaxis.major_label_text_font = 'verdana'
    plot.xaxis.major_label_text_font_size = '9pt'

    plot.xgrid.band_fill_color = "grey"
    plot.xgrid.band_fill_alpha = 0.05

    #plot.xaxis.axis_label = 'Date'
    plot.yaxis.axis_label = '% Power'
    plot.yaxis.axis_label_text_font_size = "11pt"
    plot.yaxis.axis_label_text_font_style = "normal"
    plot.legend.location = "top_left"

    #ts = TimeSeries(rm, x='index', y='values')

    col = None

    def create_outages_datatable(df):

        #p("datatable columns\n"+df.columns)

        from bokeh.models import ColumnDataSource
        from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
        datefmt = DateFormatter(format="dd M yy h:mm")

        df['startdate'] = pd.to_datetime(df['startdate'], unit='s').astype(str)
        df['finishdate'] = pd.to_datetime(df['finishdate'],
                                          unit='s').astype(str)
        df['timestamp'] = pd.to_datetime(df['timestamp'], unit='s').astype(str)

        source = ColumnDataSource(df)

        p(dir(TableColumn))

        columns = [
            TableColumn(field="startdate", title="Start"),
            TableColumn(field="finishdate", title="Finish"),
            TableColumn(field="availability", title="%", width=16),
            TableColumn(field="timestamp", title="Updated At"),
        ]

        table_height = len(df) * 24 + 30
        data_table = DataTable(source=source,
                               columns=columns,
                               row_headers=True,
                               width=600,
                               height=table_height,
                               sizing_mode='scale_both')

        return source, data_table

    plot_div, dt_div, bokeh_script = '', '', ''

    user = user.lower()

    conn = get_db()
    cursor = conn.cursor()
    q = """select * from appointments where random = '{r}'""".format(r=user)

    df = pd.read_sql(con=conn, sql=q)

    if not df.empty:

        appointments = df

        for a, i in appointments.iterrows():
            start = i.startdate
            finish = i.finishdate
            setpoint = i.availability

            row_indexer = power_df[(power_df.timestamp > start)
                                   & (power_df.timestamp < finish)].index
            p(len(row_indexer))
            power_df.loc[row_indexer, 'setpoint'] = setpoint

        url = "/appointment/{windfarm}/{random}/edit/@start".format(
            windfarm=windfarm, random=user)
        #taptool = plot.select(type=TapTool)
        #taptool = rect.select(type=TapTool)

        alert_js = """
        
            console.log("PARENT: " + showDiv(source.data['jobnumber'][source.selected["1d"].indices]))

        """

    # Add OLD Forecast Power by jittering averages of old values
    # get average values_to_take numbers and add randint
    i = 0
    values_to_take = 30

    import random

    max_index = max(power_df.index)

    while i < max_index:
        floor, ceiling = i, min(i + values_to_take - 1, max_index)
        values = power_df.loc[floor:ceiling, 'percent']
        avg = sum(values) / len(values)
        guess = avg + random.randint(-10, 10)

        guess = 0 if guess < 0 else guess
        guess = 100 if guess > 100 else guess

        power_df.loc[floor:ceiling, 'forecast'] = guess

        i += values_to_take

    now = pd.Timestamp.now().tz_localize('GMT')

    readings = []

    if appointments.finishdate.max().tz_localize('GMT') > now:

        targeted_end = (
            appointments.finishdate.max() +
            datetime.timedelta(days=2)).round('24h').tz_localize('GMT')

    else:

        targeted_end = (
            power_df.timestamp.max() +
            datetime.timedelta(days=7)).round('24h').tz_convert('GMT')

    freq = pd.Timedelta('0 days 00:10:00')

    d = now

    # test comment for git
    while d < targeted_end:

        readings.append({'timestamp': d, 'setpoint': 100})

        d += freq
        #p(d)

    forecast_av_df = pd.DataFrame(readings)

    for a, i in appointments.iterrows():
        #print(i)
        start = i.startdate
        finish = i.finishdate
        setpoint = i.availability
        #print("start", start, finish)
        row_indexer = forecast_av_df[(forecast_av_df.timestamp > start) &
                                     (forecast_av_df.timestamp < finish)].index
        #print(row_indexer, setpoint)
        forecast_av_df.loc[row_indexer, 'setpoint'] = setpoint

    previous_forecast = power_df.iloc[-1, ]['forecast']

    i = 0

    values_to_take = 6

    import random

    while i < max(forecast_av_df.index):
        floor, ceiling = i, min(i + values_to_take - 1,
                                max(forecast_av_df.index))
        guess = previous_forecast + random.randint(-1, 1)

        guess = 0 if guess < 0 else guess
        guess = 100 if guess > 100 else guess

        forecast_av_df.loc[floor:ceiling, 'forecast'] = guess

        i += values_to_take
        previous_forecast = guess

    power_source = plt.ColumnDataSource(data=power_df)

    step = plot.line(x='timestamp',
                     y='setpoint',
                     source=power_source,
                     alpha=1,
                     color='orange',
                     line_width=1)

    old_power = plot.line(x='timestamp',
                          y='forecast',
                          source=power_source,
                          alpha=1,
                          color='pink',
                          line_width=1)

    power = plot.line(x='timestamp',
                      y='percent',
                      source=power_source,
                      alpha=1,
                      color='green',
                      line_width=1)

    forecast_source = plt.ColumnDataSource(data=forecast_av_df)

    forecast = plot.line(x='timestamp',
                         y='setpoint',
                         source=forecast_source,
                         color='orange',
                         line_dash=[6, 3])

    forecast_power = plot.line(x='timestamp',
                               y='forecast',
                               source=forecast_source,
                               color='pink',
                               line_dash=[6, 6])

    legend = Legend(
        items=[
            ("Availability", [step]),
            ("Old Forecast Power", [old_power]),
            ("Actual Power", [power]),
            ("Forecast Power", [forecast_power]),
            ("Forecast Availability", [forecast]),
            #("Now", [vline])
        ],
        location=(0, -40))

    plot.add_layout(legend, 'right')

    hover_line = HoverTool(renderers=[old_power])
    hover_line.tooltips = """
        <div>
            <span style="font-size: 15px;">@date @time</span>
        </div>
        <table border="0" cellpadding="10">
            <tr>
                <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">30m avg: </span></th>
                <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@power MW</span></td>
            </tr>
            <tr>
                <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">30m min:</span></th>
                <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@hourly_min MW</span></td>
            </tr>
            <tr>
                <th><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">30m max:</span></th>
                <td><span style="font-family:'Consolas', 'Lucida Console', monospace; font-size: 12px;">@hourly_max MW</span></td>
            </tr>
        </table>
    """

    plot.add_tools(hover_line)

    source, data_table = create_outages_datatable(df)
    source.callback = CustomJS(args=dict(source=source), code=alert_js)

    #plot.legend.location = "top_left"
    plot.legend.click_policy = "hide"
    #plot.legend.background_fill_alpha = 0.01
    #plot.legend.location=(10, -30)

    from bokeh.layouts import column
    col = column(plot, data_table)

    leg = [
        rend for rend in plot.renderers
        if type(rend) == bokeh.models.annotations.Legend
    ][0]

    bokeh_script, comps = components({
        "plot": plot,
        "dt": data_table,
        "legend": leg
    })
    plot_div, dt_div, legend_div = comps['plot'], comps['dt'], comps['legend']

    if not col:
        col = plot
        bokeh_script, plot_div = components(plot)

    if not outlook:
        template = "l2.html"
    else:
        template = "outlook.html"

    p("TEMPLATE BEING USED: " + template)
    return render_template(template,
                           windfarm=windfarm,
                           random=user,
                           plot_div=plot_div,
                           dt_div=dt_div,
                           bs=bokeh_script,
                           legend_div=legend_div)
Exemplo n.º 11
0
def get_plot(raw, today):

    dfs, cats = get_sources_and_categories(raw)

    # Some times

    first_day = raw.loc[0, 'timestamp']
    one_week_ago = today - datetime.timedelta(weeks=1)
    two_weeks_ago = today - datetime.timedelta(weeks=2)
    one_week_forward = today + datetime.timedelta(weeks=1)

    # The ranges
    all_range = Range1d(start=first_day, end=today)
    month_range = Range1d(start=two_weeks_ago, end=one_week_forward)
    week_range = Range1d(start=one_week_ago, end=today)

    # Selection indicators
    highlight = Quad(
        left='start', right='end', bottom=0, top=12,
        fill_color='white', line_color=COLOR_PRIMARY_CONTRAST, fill_alpha=0.2,
    )
    lowlight = Quad(
        left='start', right='end', bottom=0, top=12,
        fill_color=COLOR_PRIMARY, line_color=COLOR_PRIMARY_CONTRAST, fill_alpha=0.5,
    )

    # Make the complete timeline plot
    all_plot = _make_base_plot(dfs, cats, all_range)
    detail_selection_source = ColumnDataSource({
        'start': [all_range.start, month_range.end],
        'end': [month_range.start, all_range.end]
    })
    all_plot.add_glyph(detail_selection_source, lowlight)
    # add a second axis to all_layout plot for presentation
    year_ticker = DatetimeTicker(desired_num_ticks=4)
    year_ticks = DatetimeTickFormatter(
        formats={
            'years': ["%Y"],
            'months': ["%Y"],
            'days': ["%Y"],
            'hours': ["%Y"]
        }
    )
    all_plot.add_layout(
        DatetimeAxis(formatter=year_ticks, ticker=year_ticker, **AXIS_PROPERTIES),
        'below'
    )

    # Make the detail plot
    detail_plot = _make_base_plot(dfs, cats, month_range)
    detail_plot.add_tools(PanTool(dimensions=['width']))
    detail_plot.add_tools(WheelZoomTool(dimensions=['width']))
    detail_plot.add_tools(ResetTool())

    week_selection_source = ColumnDataSource({'start': [week_range.start], 'end': [week_range.end]})
    detail_plot.add_glyph(week_selection_source, highlight)

    detail_code = """
        // Update the month selection box on the all_data plot when month pans
        var detail_selection_data = detail_selection_source.get('data');
        var detail_start = cb_obj.get('frame').get('x_range').get('start');
        var detail_end = cb_obj.get('frame').get('x_range').get('end');
        new_detail_selection = {
            'start': [detail_selection_data['start'][0], detail_end],
            'end': [detail_start, detail_selection_data['end'][1]]
        };
        detail_selection_source.set('data', new_detail_selection);

        // Always make sure the week highlight box on detail is visible and centered
        var x = moment.duration(detail_end - detail_start).asWeeks() / 2.4;
        var start = moment(detail_start);

        var week_end = start.add(x, 'weeks').format('x');
        $("#one_week_before").text(start.format('ddd, DD MMM YYYY'));
        var newStart = start.format('YYYY-MM-DD');
        var week_start = start.add(6, 'days').format('x');
        $("#today").text(start.format('ddd, DD MMM YYYY'));

        new_week_selection = {
            'start': [week_start, ],
            'end': [week_end, ]
        };
        week_selection_source.set('data', new_week_selection);

        var url = '/timesheet/?start=' + newStart;
        $("#timesheet_submit").attr('href', url).addClass("mdl-button--colored");
    """

    detail_xrange_callback = CustomJS(args={}, code=detail_code)
    detail_xrange_callback.args['detail_selection_source'] = detail_selection_source
    detail_xrange_callback.args['week_selection_source'] = week_selection_source
    detail_plot.x_range.callback = detail_xrange_callback

    return all_plot, detail_plot
Exemplo n.º 12
0
    result['end_shares'] = shares
    results.append(result)
    if bal < 1 and shares < 1:
        break

print('Starting position: %s' % results[0])
print('Ending position: %s' % results[-1])

output_file("datetime.html")

# create a new plot with a datetime axis type
p = figure(width=800, height=800, x_axis_type="datetime")

p.line([r['snap_dt'] for r in results], [r['end_bal'] for r in results],
       color='navy',
       alpha=0.5)

p.xaxis[0].ticker = DatetimeTicker(desired_num_ticks=20)

p.xaxis.formatter = DatetimeTickFormatter(
    hours=["%Y-%m-%d"],
    days=["%Y-%m-%d"],
    months=["%Y-%m-%d"],
    years=["%Y-%m-%d"],
)

p.xaxis.major_label_orientation = pi / 4

output_file('balance.html')
show(p)
Exemplo n.º 13
0
def plot_2T(date_time, stations, models):
    """

    :param date_time: 必须是'YYMMDDHH'形式
    :param stations:
    :param models:
    :return:
    """
   
    tabs = []
    output_file('D:/LPWF/2T_Forecast.html', title=u'2米温度预报', mode='inline')

    names = [name for name in stations] + ['date_time_X', 'date_time_str']
    
    tools_to_show = 'hover,box_zoom,pan,save,resize,reset,wheel_zoom'
    
    #注意颜色的个数一定要与站点个数相同,不然以少的为准
    colors = ['red', 'blue', 'green', 'orange', 'yellow', 'purple', 'pink', 'violet'] 

    for model in models:
        #######添加新模式需要注意修改的地方:
        # 处理u'河南WRF_RUC'的'YYYYMMDDHH'形式
        if model == u'河南WRF_RUC':
            date_time_condition = (datetime.strptime('20' + date_time, '%Y%m%d%H') - timedelta(hours=8)).strftime(
                '%Y%m%d%H')
        elif model == u'GRAPES_MESO集合平均':
            date_time_condition = (datetime.strptime('20' + date_time, '%Y%m%d%H') - timedelta(hours=8)).strftime(
                '%y%m%d%H')
        else:
            date_time_condition = date_time

        data = []
        files_list = searchProductFiles(date_time_condition, models[model])

        for each in files_list:
            d = Diamond4(each)
            lon_lat_s = [stations[name][1] for name in stations]
            extracted_values = d.IDW(lon_lat_s)
            
            #######添加新模式需要注意修改的地方:
            # 处理时间索引
            date_time_index = d.valid_time
            if model in [u'河南WRF_RUC', u'GRAPES_GFS', u'GRAPES_MESO', u'T639粗',u'GRAPES_MESO集合平均']:
                date_time_index += timedelta(hours=8)

            # 注意bokeh在将时间对象作为X轴时会将本地时间转换为世界时,为了避免这种转换,需要再本地时间上再加上8h(北京时比世界时快8h)
            extracted_values.extend([date_time_index + timedelta(hours=8), date_time_index.strftime("%m/%d %Hh")])
            data.append(pd.DataFrame(extracted_values, index=names).T)

        # 如果没有数据,则返回,防止出错
        if not data:
            continue

        df = pd.concat(data).sort_values('date_time_X', ascending=False)
        del data

        n_series = len(df)

        p = figure(plot_width=1920 - 140, plot_height=1200 - 250,
                   x_axis_type="datetime", tools=tools_to_show, active_scroll="wheel_zoom")

        # 分别为每个站点绘制时间序列变化曲线
        for name, color in zip(stations, colors):
            source = ColumnDataSource(data={
                'dateX': df['date_time_X'],
                'v': df[name],
                'dateX_str': df['date_time_str'],
                'name': [name for n in xrange(n_series)]
            })

            p.line('dateX', 'v', color=color, legend=name, source=source)
            circle = p.circle('dateX', 'v', fill_color="white", size=8, color=color, legend=name, source=source)
            p.tools[0].renderers.append(circle)

        # 图例显示策略
        p.legend.click_policy = "hide"
        # 显示标签
        hover = p.select(dict(type=HoverTool))
        hover.tooltips = [(u"温度", "@v{0.0}"), (u"站点", "@name"), (u"时间", "@dateX_str")]
        hover.mode = 'mouse'

        # 标题设置
        if model == u'EC细 2TMax_3h':
            title = ' '.join([date_time, u'EC细', u'过去3小时2米最高温度预报'])
        elif model == u'EC细 2TMin_3h':
            title = ' '.join([date_time, u'EC细', u'过去3小时2米最低温度预报'])
        else:
            title = ' '.join([date_time, model, u'2米温度预报'])
        p.title.text = title

        p.title.align = "center"
        p.title.text_font_size = "25px"
        # p.title.background_fill_color = "#aaaaee"
        # p.title.text_color = "orange"
        p.xaxis.axis_label = u'日期/时间'
        p.yaxis.axis_label = u'温度(℃)'
        
        p.xaxis[0].formatter = DatetimeTickFormatter(hours=['%m/%d %Hh', '%m/%d %H:%M'], days=['%m/%d %Hh'])
        p.xaxis[0].ticker = DatetimeTicker(desired_num_ticks=20, num_minor_ticks=4)

        # todo.根据上午还是下午确定不同的日界线
        #location使用实数表示,所以必须把时间转换成时间戳,但不清楚为什么要乘以1000
        dateX = df['date_time_X'].tolist()
        del df
        n_days = (dateX[0] - dateX[-1]).days + 1
       
        forecast_span = [
            Span(location=time.mktime((dateX[-1] + timedelta(days=i) + timedelta(hours=12)).timetuple()) * 1000,
                 dimension='height', line_color='red', line_dash='dashed', line_width=2)
            for i in xrange(n_days)]
        for span in forecast_span:
            p.add_layout(span)

        tab = Panel(child=p, title=model)
        tabs.append(tab)
    tabs = Tabs(tabs=tabs)
    save(tabs)  # 直接保存就行