I have a dbc.Container
in an app showing various cards with basic data. But I want to replace them with Gauge Charts
as the cards look clunky and i feel like the gauge charts would do a better job.
When I initially started, I wanted to add the gauge chart inside a dbc.Card
item.
I got an initial idea from this SO link and added a sample card to see how it would look like. But it came up as shown in the screenshot below.
Removing all the formatting, I tried the gauge chart and got the same situation. I also tried a simple plotly.express
line chart and have the same output. Meanwhile a DCC
or even a DBC
table shows fine in the same place.
Below is the container for the overview page:
import pandas as pd
from sqlalchemy import create_engine
from dash import html, dcc
import dash_bootstrap_components as dbc
from datetime import datetime
from conversions import *
import plotly.express as px
import plotly.graph_objects as go
def overview():
engine = create_engine("sqlite:///greenhouse.db", echo=False)
with engine.connect() as conn:
ghdata=pd.read_sql("""select *
from
SENSOR_DATA
where
MEASURE_DATE = (select
max(MEASURE_DATE)
from
SENSOR_DATA);""", conn)
wadata=pd.read_sql("""select *
from
WEATHER_API_DATA
where
MEASURE_DATE = (select
max(MEASURE_DATE)
from
WEATHER_API_DATA);""", conn)
unit = pd.read_sql("""select UNIT
from
SETTING_DATA
where
MEASURE_DATE = (select max(MEASURE_DATE) from SETTING_DATA);""", conn).values[0][0]
units = pd.read_sql(f"""select * from UNITS where UNIT = '{unit}';""", conn).values[0]
temp_unit = units[2]
speed_unit = units[1]
precip_unit = units[3]
if unit == "SI":
current_gh_temp = convert_to_fahrenheit(ghdata[['TEMPERATURE']].values[0][0])
min_temp = convert_to_fahrenheit(ghdata[['MIN_TEMP']].values[0][0])
max_temp = convert_to_fahrenheit(ghdata[['MAX_TEMP']].values[0][0])
current_wa_temp = convert_to_fahrenheit(wadata[['CURRENT_TEMPERATURE']].values[0][0])
else:
current_gh_temp = ghdata[['TEMPERATURE']].values[0][0]
min_temp = ghdata[['MIN_TEMP']].values[0][0]
max_temp = ghdata[['MAX_TEMP']].values[0][0]
current_wa_temp = wadata[['CURRENT_TEMPERATURE']].values[0][0]
print(current_gh_temp)
currenttime_card = dbc.Card([
dbc.CardHeader("Current Time"),
dbc.CardBody([html.H5(f"{datetime.now().replace(microsecond=0)}")])
],
outline=True,
)
lastmeasuredtime_card = dbc.Card([
dbc.CardHeader("Last Measured"),
dbc.CardBody([html.H5(f"{ghdata[['MEASURE_DATE']].values[0][0]}")])
],
outline=True,
)
temp_card = dbc.Card([
dbc.CardHeader("Current Temperature"),
dbc.CardBody([
html.H5(f"{current_gh_temp} {temp_unit}"),
dbc.Button("History", color="primary")
]
)
],
outline=True,
)
mintemp_card = dbc.Card([
dbc.CardHeader("Minimum"),
dbc.CardBody([
html.H5(f"{min_temp} {temp_unit}"),
]
)
],
outline=True,
)
maxtemp_card = dbc.Card([
dbc.CardHeader("Maximum"),
dbc.CardBody([
html.H5(f"{max_temp} {temp_unit}"),
]
)
],
outline=True,
)
card_grp1 = dbc.CardGroup([currenttime_card, lastmeasuredtime_card])
card_grp2 = dbc.CardGroup([mintemp_card, temp_card, maxtemp_card])
# temp_guage = html.Div(
# dcc.Graph(figure=
# px.line(
# ghdata,
# x="MEASURE_DATE",
# y=["TEMPERATURE", "MIN_TEMP"]
# )
# )
# )
temp_guage = html.Div(
dcc.Graph(figure=go.Figure
(
go.Indicator(
mode="gauge+number",
value=current_gh_temp,
domain={"x": [0,1], 'y':[0,1],},
title={"text": f"Temperature ({temp_unit})"}
)
)
)
)
# temp_guage=dbc.Table.from_dataframe(ghdata[[]])
return dbc.Container(
dbc.Col(
[
html.Br(),
dbc.Row(
[
dbc.Col(
[
card_grp1,
]
)
],
justify="center"
),
html.Br(),
dbc.Row(
[
dbc.Col(
[
dbc.Row(card_grp2),
# dbc.Row(card_grp3), # Code removed to get minimal reproducable output
]
),
# dbc.Col(card_grp4) # Code removed to get minimal reproducable output
],
justify="center"
),
html.Br(),
dbc.Row(
[
dbc.Col(
[
temp_guage
]
)
]
),
]
)
)
The returned item is just called into a container on app.py
If anybody could shed light on what I am missing, I would greatly appreciate it. Please also let me know if any additional data or information is needed to help answer my question. Thanks in advance.
Edit: Sample data as requested by Derek
unit:str = 'METRIC'
units:list = ['METRIC' 'KMPH' '°C' 'CM']
ghdata:pd.DataFrame = [
{
"MEASURE_DATE":"2024-07-25 13:40:00",
"TEMPERATURE":25,"HUMIDITY":33,
"PHOTORESISTOR_VOLTAGE":0.035,
"MIN_TEMP":24,
"MAX_TEMP":25,
"MIN_HUM":33,
"MAX_HUM":36,
"DEVICE_NAME":"PICOW-2"
}
]
wadata:pd.DataFrame = [
{
"LATITUDE":39.53,
"LONGITUDE":-119.76,
"TIMEZONE":"America\/Los_Angeles",
"TIMEZONE_ABBR":"PDT",
"MEASURE_DATE":"2024-08-02 14:00:00",
"CURRENT_TEMPERATURE":37,
"CURRENT_HUMIDITY":12,
"CURRENT_PRECIPITATION":0,
"CURRENT_WEATHER_CODE":"Overcast",
"CURRENT_WIND_SPEED":1,
"CURRENT_WIND_DIRECTION":34,
"DAILY_WEATHER_CODE":"Overcast",
"DAILY_TEMPERATURE_MAX":38,
"DAILY_TEMPERATURE_MIN":18,
"DAILY_WIND_SPEED_MAX":20,
"SUNRISE_TIME":"2024-08-02 06:00:00",
"SUNSET_TIME":"2024-08-02 20:10:00",
"TEMPERATURE_UNIT":"\u00b0C",
"HUMIDITY_UNIT":"%",
"PRECIPITATION_UNIT":"mm",
"WIND_SPEED_UNIT":"km\/h",
"WIND_DIRECTION_UNIT":"\u00b0"
}
]
As I was banging my head to the wall, figured, I would clone this on my work PC and it worked perfectly! After additional inspection, identified that some files & folders were missing from the plotly
folder in my home PC! Reinstalled plotly
using pip
and I'm back in business.
Mods may please close this question. Thank you.