def get_figures(trips: Trips, charging: List[dict]): global consumption_fig, consumption_df, trips_map, consumption_fig_by_speed, table_fig, info, battery_info, \ battery_table, consumption_graph_by_temp lats = [] lons = [] names = [] for trip in trips: for points in trip.positions: lats = np.append(lats, points.latitude) lons = np.append(lons, points.longitude) names = np.append(names, [str(trip.start_at)]) lats = np.append(lats, None) lons = np.append(lons, None) names = np.append(names, None) trips_map = px.line_mapbox(lat=lats, lon=lons, hover_name=names, mapbox_style="stamen-terrain", zoom=12) # table nb_format = Format(precision=2, scheme=Scheme.fixed, symbol=Symbol.yes) # pylint: disable=no-member table_fig = dash_table.DataTable( id='trips-table', sort_action='native', sort_by=[{ 'column_id': 'id', 'direction': 'desc' }], columns=[{ 'id': 'id', 'name': '#', 'type': 'numeric' }, { 'id': 'start_at', 'name': 'start at', 'type': 'datetime' }, { 'id': 'duration', 'name': 'duration', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" min").precision(0) }, { 'id': 'speed_average', 'name': 'average speed', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" km/h").precision(0) }, { 'id': 'consumption_km', 'name': 'average consumption', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" kWh/100km") }, { 'id': 'consumption_fuel_km', 'name': 'average consumption fuel', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" L/100km") }, { 'id': 'distance', 'name': 'distance', 'type': 'numeric', 'format': nb_format.symbol_suffix(" km").precision(1) }, { 'id': 'mileage', 'name': 'mileage', 'type': 'numeric', 'format': nb_format }, { 'id': 'altitude_diff', 'name': 'Altitude diff', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" m").precision(0) }], style_data_conditional=[{ 'if': { 'column_id': ['altitude_diff'] }, 'color': 'dodgerblue', "text-decoration": "underline" }], data=trips.get_info(), page_size=50) # consumption_fig consumption_df = DataFrame.from_records(trips.get_long_trips()) consumption_fig = px.histogram(consumption_df, x="date", y="consumption_km", title='Consumption of the car', histfunc="avg") consumption_fig.update_layout(yaxis_title="Consumption kWh/100Km") consumption_fig_by_speed = px.histogram(consumption_df, x="speed", y="consumption_km", histfunc="avg", title="Consumption by speed") consumption_fig_by_speed.update_traces(xbins_size=15) consumption_fig_by_speed.update_layout(bargap=0.05) consumption_fig_by_speed.add_trace( go.Scatter(mode="markers", x=consumption_df["speed"], y=consumption_df["consumption_km"], name="Trips")) consumption_fig_by_speed.update_layout(xaxis_title="average Speed km/h", yaxis_title="Consumption kWh/100Km") kw_per_km = float(consumption_df["consumption_km"].mean()) info = "Average consumption: {:.1f} kWh/100km".format(kw_per_km) # charging charging_data = DataFrame.from_records(charging) co2_per_kw = __calculate_co2_per_kw(charging_data) co2_per_km = co2_per_kw * kw_per_km / 100 try: charge_speed = 3600 * charging_data["kw"].mean() / \ (charging_data["stop_at"] - charging_data["start_at"]).mean().total_seconds() price_kw = (charging_data["price"] / charging_data["kw"]).mean() total_elec = kw_per_km * trips.get_distance() / 100 except (TypeError, KeyError, ZeroDivisionError): # when there is no data yet: charge_speed = 0 price_kw = 0 total_elec = 0 SUMMARY_CARDS["Average charge speed"]["text"] = f"{charge_speed:.2f} kW" SUMMARY_CARDS["Average emission"]["text"] = [ html.P(f"{co2_per_km:.1f} g/km"), html.P(f"{co2_per_kw:.1f} g/kWh") ] SUMMARY_CARDS["Electricity consumption"]["text"] = [f"{total_elec:.0f} kWh", html.Br(), \ f"{total_elec * price_kw:.0f} {ElecPrice.currency}"] SUMMARY_CARDS["Average consumption"][ "text"] = f"{consumption_df['consumption_km'].mean():.1f} kWh/100km" battery_table = dash_table.DataTable( id='battery-table', sort_action='native', sort_by=[{ 'column_id': 'start_at', 'direction': 'desc' }], columns=[{ 'id': 'start_at', 'name': 'start at', 'type': 'datetime' }, { 'id': 'stop_at', 'name': 'stop at', 'type': 'datetime' }, { 'id': 'start_level', 'name': 'start level', 'type': 'numeric' }, { 'id': 'end_level', 'name': 'end level', 'type': 'numeric' }, { 'id': 'co2', 'name': 'CO2', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" g/kWh").precision(1) }, { 'id': 'kw', 'name': 'consumption', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" kWh").precision(2) }, { 'id': 'price', 'name': 'price', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" " + ElecPrice.currency).precision(2), 'editable': True }], data=charging, style_data_conditional=[{ 'if': { 'column_id': ['start_level', "end_level"] }, 'color': 'dodgerblue', "text-decoration": "underline" }, { 'if': { 'column_id': 'price' }, 'backgroundColor': 'rgb(230, 246, 254)' }], ) consumption_by_temp_df = consumption_df[ consumption_df["consumption_by_temp"].notnull()] if len(consumption_by_temp_df) > 0: consumption_fig_by_temp = px.histogram( consumption_by_temp_df, x="consumption_by_temp", y="consumption_km", histfunc="avg", title="Consumption by temperature") consumption_fig_by_temp.update_traces(xbins_size=2) consumption_fig_by_temp.update_layout(bargap=0.05) consumption_fig_by_temp.add_trace( go.Scatter(mode="markers", x=consumption_by_temp_df["consumption_by_temp"], y=consumption_by_temp_df["consumption_km"], name="Trips")) consumption_fig_by_temp.update_layout( xaxis_title="average temperature in °C", yaxis_title="Consumption kWh/100Km") consumption_graph_by_temp = html.Div( Graph(figure=consumption_fig_by_temp), id="consumption_graph_by_temp") else: consumption_graph_by_temp = html.Div(Graph(style={'display': 'none'}), id="consumption_graph_by_temp") return True
def update_format_table( fixed_checkbox, decimal_char, precision, si_prefix, options_checklist, nan, scheme_dd, symbol_pct_radio, prefix, suffix, width, fill_char, align_val, group_checkbox, group_char, groupings, ): code = {} formatted = Format() if fixed_checkbox: formatted = formatted.scheme(Scheme.fixed) code[1] = ".scheme(Scheme.fixed)" if decimal_char: formatted = formatted.decimal_delimiter(decimal_char) code[2] = f".decimal_delimiter('{decimal_char}')" if precision: formatted = formatted.precision(int(precision)) code[3] = f".precision({int(precision)})" if si_prefix: si_prefix = None if si_prefix == "None" else si_prefix formatted = formatted.si_prefix(si_prefix) code[4] = f".si_prefix({si_prefix})" if symbol_pct_radio == "percentage": formatted = formatted.scheme(Scheme.percentage) code[5] = f".scheme(Scheme.percentage)" if "plus_minus" in options_checklist: formatted = formatted.sign(Sign.positive) code[6] = f".sign(Sign.positive)" if "parantheses" in options_checklist: formatted = formatted.sign(Sign.parantheses) code[7] = f".sign(Sign.parantheses)" if "trim" in options_checklist: formatted = formatted.trim(Trim.yes) code[8] = f".trim(Trim.yes)" if nan: print("nan", nan) formatted = formatted.nully(nan) code[9] = f".nully('{nan}')" if scheme_dd: formatted = formatted.scheme(scheme_dd) code[10] = f".scheme('{scheme_dd}')" if symbol_pct_radio == "symbol": formatted = formatted.symbol(Symbol.yes) code[11] = f".symbol(Symbol.yes)" if symbol_pct_radio == "none": code[11] = None code[5] = None if prefix: formatted = formatted.symbol_prefix(prefix) code[12] = f".symbol_prefix('{prefix}')" if suffix: formatted = formatted.symbol_suffix(suffix) code[13] = f".symbol_suffix('{suffix}')" if width: formatted = formatted.padding_width(int(width)) code[14] = f".padding_width({int(width)})" if fill_char: formatted = formatted.fill(fill_char) code[15] = f".fill('{fill_char}')" if align_val: formatted = formatted.align(align_val) code[16] = f".align('{align_val}')" if group_checkbox: formatted = formatted.group(Group.yes) code[17] = f".group(Group.yes)" if group_char: formatted = formatted.group_delimiter(group_char) code[18] = f".group_delimiter('{group_char}')" if groupings: formatted = formatted.groups(int(groupings)) code[19] = f".groups({int(groupings)})" columns = [ {"name": i, "id": i, "type": "numeric", "format": formatted} for i in df.columns ] code = ["formatted = formatted"] + list(code.values()) code = [] if code == ["formatted = formatted", None, None] else code to_json = ["formatted = "] + [str(formatted.to_plotly_json())] return columns, code, to_json
def get_figures(trips: Trips, charging: Tuple[dict]): global consumption_fig, consumption_df, trips_map, consumption_fig_by_speed, table_fig, info, battery_info, \ battery_table, consumption_graph_by_temp lats = [] lons = [] names = [] for trip in trips: for points in trip.positions: lats = np.append(lats, points.longitude) lons = np.append(lons, points.latitude) names = np.append(names, [str(trip.start_at)]) lats = np.append(lats, None) lons = np.append(lons, None) names = np.append(names, None) trips_map = px.line_mapbox(lat=lats, lon=lons, hover_name=names, mapbox_style="stamen-terrain", zoom=12) # table nb_format = Format(precision=2, scheme=Scheme.fixed, symbol=Symbol.yes) table_fig = dash_table.DataTable( id='trips-table', sort_action='native', # sort_by=[{'column_id': 'start_at', 'direction': 'desc'}], columns=[{'id': 'start_at', 'name': 'start at', 'type': 'datetime'}, {'id': 'duration', 'name': 'duration', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" min").precision(0)}, {'id': 'speed_average', 'name': 'average speed', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" km/h").precision(0)}, {'id': 'consumption_km', 'name': 'average consumption', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" kWh/100km")}, {'id': 'consumption_fuel_km', 'name': 'average consumption fuel', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" L/100km")}, {'id': 'distance', 'name': 'distance', 'type': 'numeric', 'format': nb_format.symbol_suffix(" km").precision(1)}, {'id': 'mileage', 'name': 'mileage', 'type': 'numeric', 'format': nb_format.symbol_suffix(" km").precision(1)}], data=[tr.get_info() for tr in trips[::-1]], page_size=50 ) # consumption_fig consumption_df = DataFrame.from_records(trips.get_long_trips()) consumption_fig = px.line(consumption_df, x="date", y="consumption", title='Consumption of the car') consumption_fig.update_layout(yaxis_title="Consumption kWh/100Km") consumption_fig_by_speed = px.histogram(consumption_df, x="speed", y="consumption_km", histfunc="avg", title="Consumption by speed") consumption_fig_by_speed.update_traces(xbins_size=15) consumption_fig_by_speed.update_layout(bargap=0.05) consumption_fig_by_speed.add_trace( go.Scatter(mode="markers", x=consumption_df["speed"], y=consumption_df["consumption_km"], name="Trips")) consumption_fig_by_speed.update_layout(xaxis_title="average Speed km/h", yaxis_title="Consumption kWh/100Km") kw_per_km = float(consumption_df["consumption_km"].mean()) info = "Average consumption: {:.1f} kWh/100km".format(kw_per_km) # charging charging_data = DataFrame.from_records(charging) co2_per_kw = __calculate_co2_per_kw(charging_data) co2_per_km = co2_per_kw * kw_per_km / 100 try: charge_speed = 3600 * charging_data["kw"].mean() / \ (charging_data["stop_at"] - charging_data["start_at"]).mean().total_seconds() except (TypeError, KeyError): # when there is no data yet: charge_speed = 0 battery_info = dash_table.DataTable( id='battery_info', sort_action='native', columns=[{'id': 'name', 'name': ''}, {'id': 'value', 'name': ''}], style_header={'display': 'none'}, style_data={'border': '0px'}, data=[{"name": "Average emission:", "value": "{:.1f} g/km".format(co2_per_km)}, {"name": " ", "value:": "{:.1f} g/kWh".format(co2_per_kw)}, {"name": "Average charge speed:", "value": "{:.3f} kW".format(charge_speed)}]) battery_info = html.Div(children=[html.Tr( [ html.Td('Average emission:', rowSpan=2), html.Td("{:.1f} g/km".format(co2_per_km)), ] ), html.Tr( [ "{:.1f} g/kWh".format(co2_per_kw), ] ), html.Tr( [ html.Td("Average charge speed:"), html.Td("{:.3f} kW".format(charge_speed)) ] ) ]) battery_table = dash_table.DataTable( id='battery-table', sort_action='native', sort_by=[{'column_id': 'start_at', 'direction': 'desc'}], columns=[{'id': 'start_at', 'name': 'start at', 'type': 'datetime'}, {'id': 'stop_at', 'name': 'stop at', 'type': 'datetime'}, {'id': 'start_level', 'name': 'start level', 'type': 'numeric'}, {'id': 'end_level', 'name': 'end level', 'type': 'numeric'}, {'id': 'co2', 'name': 'CO2', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" g/kWh").precision(1)}, {'id': 'kw', 'name': 'consumption', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" kWh").precision(3)}], data=charging, ) consumption_by_temp_df = consumption_df[consumption_df["consumption_by_temp"].notnull()] if len(consumption_by_temp_df) > 0: consumption_fig_by_temp = px.histogram(consumption_by_temp_df, x="consumption_by_temp", y="consumption_km", histfunc="avg", title="Consumption by temperature") consumption_fig_by_temp.update_traces(xbins_size=2) consumption_fig_by_temp.update_layout(bargap=0.05) consumption_fig_by_temp.add_trace( go.Scatter(mode="markers", x=consumption_by_temp_df["consumption_by_temp"], y=consumption_by_temp_df["consumption_km"], name="Trips")) consumption_fig_by_temp.update_layout(xaxis_title="average temperature in °C", yaxis_title="Consumption kWh/100Km") consumption_graph_by_temp = Graph(figure=consumption_fig_by_temp, id="consumption_fig_by_temp") else: consumption_graph_by_temp = Graph(style={'display': 'none'})
def get_figures(car: Car): global consumption_fig, consumption_df, trips_map, consumption_fig_by_speed, table_fig, info, \ battery_table, consumption_fig_by_temp lats = [42, 41] lons = [1, 2] names = ["undefined", "undefined"] trips_map = px.line_mapbox(lat=lats, lon=lons, hover_name=names, zoom=12, mapbox_style="style.json") trips_map.add_trace(go.Scattermapbox( mode="markers", marker={"symbol": "marker", "size": 20}, lon=[lons[0]], lat=[lats[0]], showlegend=False, name="Last Position")) # table nb_format = Format(precision=2, scheme=Scheme.fixed, symbol=Symbol.yes) # pylint: disable=no-member style_cell_conditional = [] if car.is_electric(): style_cell_conditional.append({'if': {'column_id': 'consumption_fuel_km', }, 'display': 'None', }) if car.is_thermal(): style_cell_conditional.append({'if': {'column_id': 'consumption_km', }, 'display': 'None', }) table_fig = dash_table.DataTable( id='trips-table', sort_action='custom', sort_by=[{'column_id': 'id', 'direction': 'desc'}], columns=[{'id': 'id', 'name': '#', 'type': 'numeric'}, {'id': 'start_at_str', 'name': 'start at', 'type': 'datetime'}, {'id': 'duration', 'name': 'duration', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" min").precision(0)}, {'id': 'speed_average', 'name': 'average speed', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" km/h").precision(0)}, {'id': 'consumption_km', 'name': 'average consumption', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" kWh/100km")}, {'id': 'consumption_fuel_km', 'name': 'average consumption fuel', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" L/100km")}, {'id': 'distance', 'name': 'distance', 'type': 'numeric', 'format': nb_format.symbol_suffix(" km").precision(1)}, {'id': 'mileage', 'name': 'mileage', 'type': 'numeric', 'format': nb_format}, {'id': 'altitude_diff', 'name': 'Altitude diff', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" m").precision(0)} ], style_data_conditional=[ { 'if': {'column_id': ['altitude_diff']}, 'color': 'dodgerblue', "text-decoration": "underline" } ], style_cell_conditional=style_cell_conditional, data=[], page_size=50 ) # consumption_fig consumption_fig = px.histogram(x=[0], y=[1], title='Consumption of the car', histfunc="avg") consumption_fig.update_layout(yaxis_title="Consumption kWh/100Km", xaxis_title="date") consumption_fig_by_speed = px.histogram(data_frame=[{"start_at": 1, "speed_average": 2}], x="start_at", y="speed_average", histfunc="avg", title="Consumption by speed") consumption_fig_by_speed.update_traces(xbins_size=15) consumption_fig_by_speed.update_layout(bargap=0.05) consumption_fig_by_speed.add_trace(go.Scatter(mode="markers", x=[0], y=[0], name="Trips")) consumption_fig_by_speed.update_layout(xaxis_title="average Speed km/h", yaxis_title="Consumption kWh/100Km") # battery_table battery_table = dash_table.DataTable( id='battery-table', sort_action='custom', sort_by=[{'column_id': 'start_at_str', 'direction': 'desc'}], columns=[{'id': 'start_at_str', 'name': 'start at', 'type': 'datetime'}, {'id': 'stop_at_str', 'name': 'stop at', 'type': 'datetime'}, {'id': 'start_level', 'name': 'start level', 'type': 'numeric'}, {'id': 'end_level', 'name': 'end level', 'type': 'numeric'}, {'id': 'co2', 'name': 'CO2', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" g/kWh").precision(1)}, {'id': 'kw', 'name': 'consumption', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" kWh").precision(2)}, {'id': 'price', 'name': 'price', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" " + ElecPrice.currency).precision(2), 'editable': True} ], data=[], style_data_conditional=[ { 'if': {'column_id': ['start_level', "end_level"]}, 'color': 'dodgerblue', "text-decoration": "underline" }, { 'if': {'column_id': 'price'}, 'backgroundColor': '#ABE2FB' } ], ) consumption_fig_by_temp = px.histogram(x=[0], y=[0], histfunc="avg", title="Consumption by temperature") consumption_fig_by_temp.update_traces(xbins_size=2) consumption_fig_by_temp.update_layout(bargap=0.05) consumption_fig_by_temp.add_trace( go.Scatter(mode="markers", x=[0], y=[0], name="Trips")) consumption_fig_by_temp.update_layout(xaxis_title="average temperature in °C", yaxis_title="Consumption kWh/100Km") return True
def get_figures(trips: List[Trip], charging: List[dict]): global consumption_fig, consumption_df, trips_map, consumption_fig_by_speed, table_fig, info, battery_info lats = [] lons = [] names = [] for trip in trips: for points in trip.positions: lats = np.append(lats, points.longitude) lons = np.append(lons, points.latitude) names = np.append(names, [str(trip.start_at)]) lats = np.append(lats, None) lons = np.append(lons, None) names = np.append(names, None) trips_map = px.line_mapbox(lat=lats, lon=lons, hover_name=names, mapbox_style="stamen-terrain", zoom=12) # table nb_format = Format(precision=2, scheme=Scheme.fixed, symbol=Symbol.yes) table_fig = dash_table.DataTable( id='trips-table', sort_action='native', sort_by=[{'column_id': 'start_at', 'direction': 'desc'}], columns=[{'id': 'start_at', 'name': 'start at', 'type': 'datetime'}, {'id': 'duration', 'name': 'duration', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" min").precision(0)}, {'id': 'speed_average', 'name': 'average speed', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" km/h")}, {'id': 'consumption_km', 'name': 'average consumption', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" kw/100km")}, {'id': 'distance', 'name': 'distance', 'type': 'numeric', 'format': nb_format.symbol_suffix(" km")}], data=[tr.get_info() for tr in trips], ) # consumption_fig consumption_df = DataFrame.from_records([tr.get_consumption() for tr in trips]) consumption_fig = px.line(consumption_df, x="date", y="consumption", title='Consumption of the car') consumption_fig.update_layout(yaxis_title="Consumption kWh/100Km") consum_df_by_speed = DataFrame.from_records( [{"speed": tr.speed_average, "consumption": tr.consumption_km} for tr in trips]) consumption_fig_by_speed = px.histogram(consum_df_by_speed, x="speed", y="consumption", histfunc="avg", title="Consumption by speed") consumption_fig_by_speed.update_traces(xbins_size=15) consumption_fig_by_speed.update_layout(bargap=0.05) consumption_fig_by_speed.add_trace( go.Scatter(mode="markers", x=consum_df_by_speed["speed"], y=consum_df_by_speed["consumption"], name="Trips")) consumption_fig_by_speed.update_layout(xaxis_title="average Speed km/h", yaxis_title="Consumption kWh/100Km") kw_per_km = float(consumption_df.mean(numeric_only=True)) info = "Average consumption: {:.1f} kW/100km".format(kw_per_km) # charging charging_data = DataFrame.from_records(charging) try: co2_per_kw = charging_data["co2"].sum() / charging_data["kw"].sum() except ZeroDivisionError: co2_per_kw = 0 co2_per_km = co2_per_kw * kw_per_km / 100 try: charge_speed = 3600 * charging_data["kw"].mean() / \ (charging_data["stop_at"] - charging_data["start_at"]).mean().total_seconds() except TypeError: # when there is no data yet: charge_speed = 0 battery_info = html.Div(children=[html.P("Average gC02/kW: {:.1f}".format(co2_per_kw)), html.P("Average gC02/km: {:1f}".format(co2_per_km)), html.P("Average Charge SPEED {:1f} kW/h".format(charge_speed))])