import boto3 import json import matplotlib import matplotlib.pyplot as plt import pandas as pd from l4ecwcw import * from io import StringIO from matplotlib import gridspec # Mandatory to ensure text is rendered in SVG plots: matplotlib.rcParams['svg.fonttype'] = 'none' client = boto3.client('lookoutequipment') dpi = 100 def get_predictions(event, context): model_name = event['model_name'] widget_context = event['widgetContext'] width = widget_context['width'] # Height taking into account the height of the tag selection form: height = int(widget_context['height']) - 50 tags_list = get_tags_list(model_name) tag = get_selected_tag(widget_context) if tag is None: tag = tags_list[0] svg = get_model_evaluations_infos(model_name, width, height, tag) html = build_tag_selection_form(event, context, tags_list, tag) html = html + f'
{svg}
' return html def get_tags_list(model_name): model_response = client.describe_model(ModelName=model_name) predictions = json.loads(model_response['ModelMetrics'])['predicted_ranges'] diagnostics = predictions[0]['diagnostics'] tags_list = [d['name'].split('\\')[-1] for d in diagnostics] return tags_list def get_selected_tag(widget_context): print(widget_context['forms']['all']) if len(widget_context['forms']['all']) > 0: return widget_context['forms']['all']['tags'] else: return None def get_model_evaluations_infos(model_name, width, height, tag): model_response = client.describe_model(ModelName=model_name) predictions = json.loads(model_response['ModelMetrics'])['predicted_ranges'] start_date = pd.to_datetime(model_response['EvaluationDataStartTime']).tz_localize(None) end_date = pd.to_datetime(model_response['EvaluationDataEndTime']).tz_localize(None) df = pd.DataFrame(predictions) predictions_df = convert_ranges(df, start_date, end_date) events_df = df.copy() events_df['duration'] = pd.to_datetime(events_df['end']) - pd.to_datetime(events_df['start']) events_df['duration'] = events_df['duration'].dt.total_seconds() / 3600 component_name = json.loads(model_response['Schema'])['Components'][0]['ComponentName'] dataset_name = model_response['DatasetName'] dataset_response = client.describe_dataset(DatasetName=dataset_name) bucket = dataset_response['IngestionInputConfiguration']['S3InputConfiguration']['Bucket'] prefix = dataset_response['IngestionInputConfiguration']['S3InputConfiguration']['Prefix'] #+ component_name + '/' df_list = [] s3 = boto3.client('s3') for file_key in get_matching_s3_keys(bucket=bucket, prefix=prefix, suffix=('.csv', '.CSV')): try: print(f'Looking for {tag} data in file {file_key}...') csvfile = s3.get_object(Bucket=bucket, Key=file_key) df = pd.read_csv(csvfile['Body'], usecols=['Timestamp', tag]) df['Timestamp'] = pd.to_datetime(df['Timestamp']) df = df.set_index('Timestamp') df = df[start_date:end_date] df_list.append(df) except Exception as e: print(f'Tag {tag} not found in file {file_key}') timeseries_df = pd.concat(df_list, axis='index') # Prepare the figure: colors = set_aws_stylesheet() fig = plt.figure(figsize=(width*1.25/dpi, height/dpi), dpi=dpi) gs = gridspec.GridSpec(nrows=4, ncols=1, height_ratios=[8, 1.5, 5, 5], hspace=0.5) # First section: a line plot of the selected time series: ax1 = fig.add_subplot(gs[0]) plt.plot(timeseries_df) ax1.set_title(f'Tag: {tag}') # Second section: the events detected by Lookout for Equipment: ax2 = fig.add_subplot(gs[1]) plot_ranges(predictions_df, 'Detected events', colors[5], ax2) ax2.set_xlim(ax1.get_xlim()) # Third section: the number of detected events per day: ax3 = fig.add_subplot(gs[2]) ax3.plot(predictions_df.rolling(60*24).sum()) ax3.set_xlim(ax1.get_xlim()) ax3.axes.get_xaxis().set_ticks([]) ax3.set_xlabel('Number of daily event detected', fontsize=12) # # Fourth section: their averate duration: ax4 = fig.add_subplot(gs[3]) ax4.bar(pd.to_datetime(events_df['start']), events_df['duration'], color=colors[9], width=2.0, alpha=0.5) ax4.set_xlim(ax1.get_xlim()) ax4.axes.get_xaxis().set_ticks([]) ax4.set_xlabel('Average duration of detected events', fontsize=12) # Save this image to an SVG string: svg_io = StringIO() fig.savefig(svg_io, format="svg", bbox_inches='tight') return svg_io.getvalue().replace('DejaVu Sans', 'Amazon Ember') def build_tag_selection_form(event, context, tags_list, selected_tag): endpoint = context.invoked_function_arn payload = json.dumps(event) options = [] tags_list.sort() for t in tags_list: if t == selected_tag: options.append(f'') else: options.append(f'') options = '\n'.join(options) form = ( '
' '
' ' ' '' ' \n' '' 'Submit\n' f'' f'{payload}' '' '
' '
' ) return form