def _plot_energy_profile_hr(self, area: Area, subdir: str): """ Plots history of energy trades plotted for each market_slot """ area_stats = self.endpoint_buffer.area_market_stocks_stats.state[ area.name] barmode = "relative" xtitle = 'Time' ytitle = 'Energy [kWh]' market_name = area.name title = f'High Resolution Energy Trade Profile of {market_name}' plot_dir = os.path.join(self.plot_dir, subdir, "energy_profile_hr") mkdir_from_str(plot_dir) for market_slot, data in area_stats.items(): plot_data = self.add_plotly_graph_dataset(data, market_slot) if len(plot_data) > 0: market_slot_str = market_slot.format(DATE_TIME_FORMAT) output_file = \ os.path.join(plot_dir, f'energy_profile_hr_' f'{market_name}_{market_slot_str}.html') time_range = [ market_slot - GlobalConfig.tick_length, market_slot + GlobalConfig.slot_length + GlobalConfig.tick_length ] PlotlyGraph.plot_bar_graph(barmode, title, xtitle, ytitle, plot_data, output_file, time_range=time_range)
def _plot_energy_profile(self, subdir: str, market_name: str, energy_profile): """ Plots history of energy trades """ data = list() barmode = "relative" xtitle = 'Time' ytitle = 'Energy [kWh]' key = 'energy' title = 'Energy Trade Profile of {}'.format(market_name) data.extend( self._plot_energy_graph(energy_profile, market_name, "sold_energy_lists", "-seller", key, ENERGY_SELLER_SIGN_PLOTS)) data.extend( self._plot_energy_graph(energy_profile, market_name, "bought_energy_lists", "-buyer", key, ENERGY_BUYER_SIGN_PLOTS)) if len(data) == 0: return if all([len(da.y) == 0 for da in data]): return plot_dir = os.path.join(self.plot_dir, subdir) mkdir_from_str(plot_dir) output_file = os.path.join( plot_dir, 'energy_profile_{}.html'.format(market_name)) PlotlyGraph.plot_bar_graph(barmode, title, xtitle, ytitle, data, output_file)
def _plot_avg_trade_graph(self, stats, area_name, key, label): graph_obj = PlotlyGraph(stats[area_name.lower()], key) graph_obj.graph_value() data_obj = go.Scatter(x=list(graph_obj.umHours.keys()), y=list(graph_obj.umHours.values()), name=label.lower()) return data_obj
def _plot_stock_info_per_area_per_market_slot(self, area, plot_dir): """ Plots stock stats for each knot in the hierarchy per market_slot """ area_stats = self.endpoint_buffer.offer_bid_trade_hr.state[area.name] self.market_slot_data_mapping = {} fig = go.Figure() for index, (market_slot_date, markets) in enumerate(area_stats.items()): start = len(fig.data) for tick_slot, info_dicts in markets.items(): for info_dict in info_dicts: if info_dict["tag"] == "bid": tool_tip = f"{info_dict['buyer_origin']} " \ f"Bid ({info_dict['energy']} kWh @ " \ f"{round_floats_for_ui(info_dict['rate'])} € cents / kWh)" info_dict.update({"tool_tip": tool_tip}) elif info_dict["tag"] == "offer": tool_tip = f"{info_dict['seller_origin']} " \ f"Offer({info_dict['energy']} kWh @ " \ f"{round_floats_for_ui(info_dict['rate'])} € cents / kWh)" info_dict.update({"tool_tip": tool_tip}) elif info_dict["tag"] == "trade": tool_tip = f"Trade: {info_dict['seller_origin']} --> " \ f"{info_dict['buyer_origin']} " \ f"({info_dict['energy']} kWh @ " \ f"{round_floats_for_ui(info_dict['rate'])} € / kWh)" info_dict.update({"tool_tip": tool_tip}) for info_dict in info_dicts: size = 5 if info_dict["tag"] in ["offer", "bid"] else 10 all_info_dicts = list([ info_dict, *[ i for i in info_dicts if i['rate'] == info_dict['rate'] ] ]) # Removes duplicate dicts from a list of dicts all_info_dicts = [ dict(t) for t in {tuple(sorted(d.items())) for d in all_info_dicts} ] all_info_dicts.sort(key=lambda e: e["tool_tip"]) tooltip_text = "<br />".join( map(lambda e: e["tool_tip"], all_info_dicts)) fig.add_trace( go.Scatter(x=[tick_slot], y=[info_dict['rate']], text=tooltip_text, hoverinfo='text', marker=dict( size=size, color=all_info_dicts[0]['color']), visible=False)) self.market_slot_data_mapping[index] = SlotDataRange( start, len(fig.data)) PlotlyGraph.plot_slider_graph(fig, plot_dir, area.name, self.market_slot_data_mapping)
def _plot_energy_graph(self, trades, market_name, agent, agent_label, key, scale_value): internal_data = [] for trader in trades[market_name][agent].keys(): graph_obj = PlotlyGraph(trades[market_name][agent][trader], key) graph_obj.graph_value(scale_value=scale_value) data_obj = go.Bar(x=list(graph_obj.umHours.keys()), y=list(graph_obj.umHours.values()), name=trader + agent_label) internal_data.append(data_obj) return internal_data
def _plot_supply_demand_curve(self, subdir: str, area: Area): if area.slug not in self.file_stats_endpoint.clearing: return for market_slot, clearing in self.file_stats_endpoint.clearing[ area.slug].items(): data = list() xmax = 0 for time_slot, supply_curve in \ self.file_stats_endpoint.cumulative_offers[area.slug][market_slot].items(): data.append( self.render_supply_demand_curve(supply_curve, time_slot, True)) for time_slot, demand_curve in \ self.file_stats_endpoint.cumulative_bids[area.slug][market_slot].items(): data.append( self.render_supply_demand_curve(demand_curve, time_slot, False)) if len(data) == 0: continue for time_slot, clearing_point in clearing.items(): # clearing_point[0] --> Clearing-Rate # clearing_point[1] --> Clearing-Energy if len(clearing_point) != 0: data_obj = go.Scatter( x=[0, clearing_point[1]], y=[clearing_point[0], clearing_point[0]], mode='lines+markers', line=dict(width=5), name=time_slot.format(DATE_TIME_FORMAT) + ' Clearing-Rate') data.append(data_obj) data_obj = go.Scatter( x=[clearing_point[1], clearing_point[1]], y=[0, clearing_point[0]], mode='lines+markers', line=dict(width=5), name=time_slot.format(DATE_TIME_FORMAT) + ' Clearing-Energy') data.append(data_obj) xmax = max(xmax, clearing_point[1]) * 3 plot_dir = os.path.join(self.plot_dir, subdir, 'mcp') mkdir_from_str(plot_dir) output_file = os.path.join(plot_dir, f'supply_demand_{market_slot}.html') PlotlyGraph.plot_line_graph('supply_demand_curve', 'Energy (kWh)', 'Rate (ct./kWh)', data, output_file, xmax)
def _plot_ess_energy_trace(self, energy: dict, subdir: str, root_name: str): """ Plots ess energy trace for each knot in the hierarchy """ data = list() barmode = "stack" title = 'ESS ENERGY SHARE ({})'.format(root_name) xtitle = 'Time' ytitle = 'Energy [kWh]' temp = { ESSEnergyOrigin.UNKNOWN: {slot: 0. for slot in generate_market_slot_list()}, ESSEnergyOrigin.LOCAL: {slot: 0. for slot in generate_market_slot_list()}, ESSEnergyOrigin.EXTERNAL: {slot: 0. for slot in generate_market_slot_list()} } for time, energy_info in energy.items(): temp[ESSEnergyOrigin.EXTERNAL][time] = energy_info[ ESSEnergyOrigin.EXTERNAL] temp[ESSEnergyOrigin.LOCAL][time] = energy_info[ ESSEnergyOrigin.LOCAL] temp[ESSEnergyOrigin.UNKNOWN][time] = energy_info[ ESSEnergyOrigin.UNKNOWN] for energy_type in [ ESSEnergyOrigin.EXTERNAL, ESSEnergyOrigin.LOCAL, ESSEnergyOrigin.UNKNOWN ]: data_obj = go.Bar(x=list(temp[energy_type].keys()), y=list(temp[energy_type].values()), name=f"{energy_type}") data.append(data_obj) if len(data) == 0: return plot_dir = os.path.join(self.plot_dir, subdir) mkdir_from_str(plot_dir) output_file = os.path.join( plot_dir, 'ess_energy_share_{}.html'.format(root_name)) PlotlyGraph.plot_bar_graph(barmode, title, xtitle, ytitle, data, output_file)
def _plot_energy_profile(self, subdir: str, market_name: str): """ Plots history of energy trades """ data = list() barmode = "relative" xtitle = 'Time' ytitle = 'Energy [kWh]' key = 'energy' title = 'Energy Trade Profile of {}'.format(market_name) data.extend( self._plot_energy_graph( self.endpoint_buffer.trade_profile.traded_energy_profile, market_name, "sold_energy_lists", "-seller", key, ENERGY_SELLER_SIGN_PLOTS)) data.extend( self._plot_energy_graph( self.endpoint_buffer.trade_profile.traded_energy_profile, market_name, "bought_energy_lists", "-buyer", key, ENERGY_BUYER_SIGN_PLOTS)) if ConstSettings.BalancingSettings.ENABLE_BALANCING_MARKET: if "sold_energy_lists" in \ self.endpoint_buffer.trade_profile.balancing_traded_energy[market_name]: data.extend( self._plot_energy_graph( self.endpoint_buffer.trade_profile. balancing_traded_energy, market_name, "sold_energy_lists", "-balancing-seller", key, ENERGY_SELLER_SIGN_PLOTS)) data.extend( self._plot_energy_graph( self.endpoint_buffer.trade_profile. balancing_traded_energy, market_name, "bought_energy_lists", "-balancing-buyer", key, ENERGY_BUYER_SIGN_PLOTS)) if len(data) == 0: return if all([len(da.y) == 0 for da in data]): return plot_dir = os.path.join(self.plot_dir, subdir) mkdir_from_str(plot_dir) output_file = os.path.join( plot_dir, 'energy_profile_{}.html'.format(market_name)) PlotlyGraph.plot_bar_graph(barmode, title, xtitle, ytitle, data, output_file)
def _plot_stock_info_per_area_per_market_slot(self, area, plot_dir): """ Plots stock stats for each knot in the hierarchy per market_slot """ area_stats = self.endpoint_buffer.area_market_stocks_stats.state[ area.name] self.market_slot_data_mapping = {} fig = go.Figure() for index, (market_slot_date, markets) in enumerate(area_stats.items()): start = len(fig.data) for tick_slot, info_dicts in markets.items(): for info_dict in info_dicts: size = 5 if info_dict["tag"] in ["offer", "bid"] else 10 all_info_dicts = list([ info_dict, *[ i for i in info_dicts if i['rate'] == info_dict['rate'] ] ]) # Removes duplicate dicts from a list of dicts all_info_dicts = [ dict(t) for t in {tuple(sorted(d.items())) for d in all_info_dicts} ] all_info_dicts.sort(key=lambda e: e["tool_tip"]) tooltip_text = "<br />".join( map(lambda e: e["tool_tip"], all_info_dicts)) fig.add_trace( go.Scatter(x=[tick_slot], y=[info_dict['rate']], text=tooltip_text, hoverinfo='text', marker=dict( size=size, color=all_info_dicts[0]['color']), visible=False)) self.market_slot_data_mapping[index] = SlotDataRange( start, len(fig.data)) PlotlyGraph.plot_slider_graph(fig, plot_dir, area.name, self.market_slot_data_mapping)
def _plot_device_stats(self, address_list: list, device_strategy): """ Plots device graphs """ # Dont use the root area name for address list: device_address_list = address_list[1::] device_name = device_address_list[-1].replace(" ", "_") device_stats = self.endpoint_buffer.results_handler.all_raw_results[ "device_statistics"] device_dict = get_from_dict(device_stats, device_address_list) # converting address_list into plot_dir by slugifying the members plot_dir = os.path.join( self.plot_dir, "/".join([slugify(node).lower() for node in address_list][0:-1])) mkdir_from_str(plot_dir) output_file = os.path.join( plot_dir, 'device_profile_{}.html'.format(device_name)) PlotlyGraph.plot_device_profile(device_dict, device_name, output_file, device_strategy)
def _plot_ess_soc_history(self, storage_list: list, subdir: str, root_name: str): """ Plots ess soc for each knot in the hierarchy """ storage_key = 'charge [%]' data = list() barmode = "relative" title = 'ESS SOC ({})'.format(root_name) xtitle = 'Time' ytitle = 'Charge [%]' for si in storage_list: graph_obj = PlotlyGraph(self.file_stats_endpoint.plot_stats[si], storage_key) graph_obj.graph_value() data_obj = go.Scatter(x=list(graph_obj.umHours.keys()), y=list(graph_obj.umHours.values()), name=si) data.append(data_obj) if len(data) == 0: return plot_dir = os.path.join(self.plot_dir, subdir) mkdir_from_str(plot_dir) output_file = os.path.join(plot_dir, 'ess_soc_history_{}.html'.format(root_name)) PlotlyGraph.plot_bar_graph(barmode, title, xtitle, ytitle, data, output_file)
def plot_all_unmatched_loads(self): """ Plot unmatched loads of all loads in the configuration into one plot """ unmatched_key = 'deficit [kWh]' data = list() root_name = self.area.slug title = 'Unmatched Loads for all devices in {}'.format(root_name) xtitle = 'Time' ytitle = 'Energy (kWh)' barmode = 'stack' load_list = [ child_key for child_key in self.export_data.plot_stats.keys() if unmatched_key in self.export_data.plot_stats[child_key].keys() ] for li in load_list: graph_obj = PlotlyGraph(self.export_data.plot_stats[li], unmatched_key) if sum(graph_obj.dataset[unmatched_key]) < 1e-10: continue graph_obj.graph_value() data_obj = go.Bar(x=list(graph_obj.umHours.keys()), y=list(graph_obj.umHours.values()), name=li) data.append(data_obj) if len(data) == 0: return plot_dir = os.path.join(self.plot_dir) mkdir_from_str(plot_dir) output_file = os.path.join(plot_dir, 'unmatched_loads_{}.html'.format(root_name)) PlotlyGraph.plot_bar_graph(barmode, title, xtitle, ytitle, data, output_file)
def _plot_avg_trade_price(self, area_list: list, subdir: str): """ Plots average trade for the specified level of the hierarchy """ data = list() barmode = 'stack' xtitle = "Time" ytitle = "Rate [ct./kWh]" key = 'avg trade rate [ct./kWh]' title = 'Average Trade Price {}'.format(area_list[0]) for area_name in area_list: data.append( self._plot_avg_trade_graph(self.file_stats_endpoint.plot_stats, area_name, key, area_name)) if ConstSettings.BalancingSettings.ENABLE_BALANCING_MARKET and \ self.file_stats_endpoint.plot_balancing_stats[area_name.lower()] is not None: area_name_balancing = area_name.lower( ) + "-demand-balancing-trades" data.append( self._plot_avg_trade_graph( self.file_stats_endpoint.plot_balancing_stats, area_name, 'avg demand balancing trade rate [ct./kWh]', area_name_balancing)) area_name_balancing = area_name.lower( ) + "-supply-balancing-trades" data.append( self._plot_avg_trade_graph( self.file_stats_endpoint.plot_balancing_stats, area_name, 'avg supply balancing trade rate [ct./kWh]', area_name_balancing)) if all([len(da.y) == 0 for da in data]): return plot_dir = os.path.join(self.plot_dir, subdir) mkdir_from_str(plot_dir) output_file = os.path.join( plot_dir, 'average_trade_price_{}.html'.format(area_list[0])) PlotlyGraph.plot_bar_graph(barmode, title, xtitle, ytitle, data, output_file)
def _plot_trade_partner_cell_tower(self, load: str, plot_dir: str): """ Plots trade partner pie graph for the sell tower. """ higt = PlotlyGraph(self.export_data.buyer_trades, load) higt.arrange_data() mkdir_from_str(plot_dir) higt.plot_pie_chart( "Energy Trade Partners for {}".format(load), os.path.join(plot_dir, "energy_trade_partner_{}.html".format(load)))