コード例 #1
0
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
コード例 #2
0
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
コード例 #3
0
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'})
コード例 #4
0
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
コード例 #5
0
ファイル: figures.py プロジェクト: jlayec/psa_car_controller
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))])