Plotly interactive Graph Card

Did you know you can “plot” tables with a sensor history with this card?

@ mateine
Could you give me a hint how to extend the x-axis offset on the left side as it cuts off the enumation values of the first plot? I’ve tried to play with the "x: " value but it seems to no change anything.

Many thanks
Rainer

type: custom:plotly-graph
entities:
  - entity: sensor.eu08l_hp1_operating_state_txt
    name: Op-State
    yaxis: "y"
    show_value: true
    fillcolor: lightblue
  - entity: sensor.eu08l_hp1_request_type
    yaxis: y2
    name: Req-Type
    mode: lines
    show_value: true
    line:
      shape: line
      color: green
      width: 1
  - entity: sensor.templogger_temperatur_kanal_0
    name: Temperatur Vorlauf - SHT45 - not used
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: orange
      width: 1
  - entity: sensor.EU08L_Hp1_Flow_Line_Temperature
    name: Temperatur Vorlauf
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_Hp1_return_line_temperature
    name: Temperatur Rücklauf
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: blue
      width: 1
  - entity: sensor.eu08l_boil1_set_temperature
    name: Temperatur Soll
    yaxis: y4
    mode: lines
    show_value: true
    line:
      shape: line
      color: cyan
      width: 1
  - entity: sensor.eu08l_boil1_actual_high_temperature
    name: Temperatur Oben
    yaxis: y4
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_boil1_actual_low_temperature
    name: Temperatur Mitte
    yaxis: y4
    mode: lines
    show_value: true
    line:
      shape: line
      color: blue
      width: 1
  - entity: sensor.eu08l_hp1_inverter_power_consumption
    name: Leistung [W]
    yaxis: y5
    mode: lines
    show_value: true
    line:
      shape: line
      color: green
      width: 1
hours_to_show: 168
refresh_interval: 10
title: Heizung
layout:
  height: 1000
  grid:
    rows: 5
    columns: 1
    roworder: top to bottom
    ygap: 0.25
    pattern: coupled
  yaxis:
    title: ""
    showgrid: true
    range:
      - -1
      - 5
    fillcolor: rgba(0, 0, 220, 0.5)
  yaxis2:
    title: Req.-Type
    showgrid: true
    range:
      - -1
      - 5
  yaxis3:
    range:
      - 9
      - 61
    showgrid: true
    title: °C
  yaxis4:
    range:
      - 39
      - 61
    showgrid: true
    title: °C
  yaxis5:
    range:
      - -1
      - 8200
    showgrid: true
    title: Watt
  annotations:
    - text: Req.-Type
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.8
      yref: y domain
      font:
        size: 14
    - text: Req.-Type
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.1
      yref: y2 domain
      font:
        size: 14
    - text: Vorlauf- Rücklauf
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y3 domain
      font:
        size: 14
    - text: Speicher
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y4 domain
      font:
        size: 14
    - text: Watt
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y5 domain
      font:
        size: 14
defaults:
  yaxes:
    side: left
    overlaying: "y"
    visible: true
  xaxis:
    rangeselector:
      "y": 1.5
      buttons:
        - count: 1
          step: minute
        - count: 15
          step: minute
        - count: 1
          step: hour
        - count: 12
          step: hour
        - count: 1
          step: day
        - count: 7
          step: day

You can increase the left margin to make space for the tick text:

layout:
  margin:
    l: 100

You could also slant the text a bit with:

layout:
  yaxis:
    tickangle: 45

@maintaine
Many thanks for the fast reply. That works.

Ist there aso a possibility to have the x-axis values inside the graph as kind of overlay?

It looks currently like this:

Many thanks for you help!
Rainer

I love plotly so I’m super excited that this is available in Home Assistant! I really want to add a dashboard for health metrics, and I have created sensors that give me the data as attributes.


I just can’t seem to plot them correctly:

I’m sure I’m missing something obvious here, can anyone point me in the right direction? Thanks a lot!

It looks like all the data is inside the attributes of a single datapoint. I think you need this: Timestamp in attribute · dbuezas/lovelace-plotly-graph-card · Discussion #458 · GitHub

For pure plotly questions it is best to google or ask chatgpt “how to … in plotlyjs”.

Thank you so much! I’ll investigate this!!

@mateine

I have the problem that the lowest line in the graph is not always shown correctly in the graph - see picture.

It is not a problem with the value - I’ve checked these - the parts which are missing in the plotly graph are correctly shown in a history card with value “Central Heating” .

Many thanks,
Rainer

type: custom:plotly-graph
entities:
  - entity: sensor.eu08l_hp1_operating_state_txt
    name: Op-State
    yaxis: "y"
    fillcolor: lightblue
  - entity: sensor.eu08l_ambient_temperature
    yaxis: y2
    name: Req-Type
    mode: lines
    show_value: true
    line:
      shape: line
      color: green
      width: 1
  - entity: sensor.templogger_temperatur_kanal_0
    name: Temperatur Vorlauf - SHT45 - not used
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: orange
      width: 1
  - entity: sensor.EU08L_Hp1_Flow_Line_Temperature
    name: Temperatur Vorlauf
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_Hp1_return_line_temperature
    name: Temperatur Rücklauf
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: blue
      width: 1
  - entity: sensor.eu08l_buffer1_actual_low_temperature
    name: Pufferspeicher Mitte
    yaxis: y4
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_boil1_set_temperature
    name: Temperatur Soll
    yaxis: y5
    mode: lines
    show_value: true
    line:
      shape: line
      color: cyan
      width: 1
  - entity: sensor.eu08l_boil1_actual_high_temperature
    name: Temperatur Oben
    yaxis: y5
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_hp1_inverter_power_consumption
    name: Leistung [W]
    yaxis: y6
    mode: lines
    show_value: true
    line:
      shape: line
      color: green
      width: 1
hours_to_show: 168
refresh_interval: 10
title: Heizung
layout:
  height: 1000
  margin:
    l: 100
  grid:
    rows: 6
    columns: 1
    roworder: top to bottom
    ygap: 0.25
    pattern: coupled
  yaxis:
    tickangle: 45
    title: ""
    showgrid: true
    fillcolor: rgba(0, 0, 220, 0.5)
  yaxis2:
    title: °C
    showgrid: true
  yaxis3:
    range:
      - 9
      - 61
    showgrid: true
    title: °C
  yaxis4:
    range:
      - 20
      - 35
    showgrid: true
    title: °C
  yaxis5:
    range:
      - 39
      - 61
    showgrid: true
    title: °C
  yaxis6:
    showgrid: true
    title: W
  annotations:
    - text: Req.-Type
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.8
      yref: y domain
      font:
        size: 14
    - text: Aussentemperetaur
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.1
      yref: y2 domain
      font:
        size: 14
    - text: Vorlauf- Rücklauf
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y3 domain
      font:
        size: 14
    - text: Puffer Speicher
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y4 domain
      font:
        size: 14
    - text: WW Speicher
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y5 domain
      font:
        size: 14
    - text: Leistung
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y6 domain
      font:
        size: 14
defaults:
  yaxes:
    side: left
    overlaying: "y"
    visible: true
  xaxis:
    rangeselector:
      "y": 1.5
      buttons:
        - count: 1
          step: minute
        - count: 15
          step: minute
        - count: 1
          step: hour
        - count: 12
          step: hour
        - count: 1
          step: day
        - count: 7
          step: day

This happens when the value is null. You can remove the nulls using a filter

entity: sensor.xxx
filters:
  - filter: y !== null
  

@RbAc

Also, I suggest you lock the order of non numeric axes: How to set fix y-axis values in a specific order? · dbuezas/lovelace-plotly-graph-card · Discussion #322 · GitHub

@mateine,
many thanks.

Unfortunately that did not solve the issue. I’ve added the “!=null” and “order layout”, but the lower horizontal line does not appear sometime.

See the graph right below a history-graph which uses the same sensor - the yellow part (Central Heating" is missing on the last three days (it was there before - 10-12 Nov) .

So I infer it is not a issue of the sensor value not available, can it do with something like rounding (although it is a enumeration (text) which is shown)

What do you think?
Rainer

History Graph YAML

cards:
  - type: history-graph
    entities:
      - entity: sensor.eu08l_hp1_operating_state_txt
        name: Mod.
      - entity: sensor.eu08l_hp1_request_type_txt
        name: Req.
    title: Betriebsmodus
    hours_to_show: 168

Plotly YAML

type: custom:plotly-graph
entities:
  - entity: sensor.eu08l_hp1_operating_state_txt
    name: Op-State
    yaxis: "y"
    fillcolor: lightblue
  - entity: sensor.eu08l_ambient_temperature
    filters:
      - filter: y !== null
    yaxis: y2
    name: Req-Type
    mode: lines
    show_value: true
    line:
      shape: line
      color: green
      width: 1
  - entity: sensor.templogger_temperatur_kanal_0
    name: Temperatur Vorlauf - SHT45 - not used
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: orange
      width: 1
  - entity: sensor.EU08L_Hp1_Flow_Line_Temperature
    name: Temperatur Vorlauf
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_Hp1_return_line_temperature
    name: Temperatur Rücklauf
    yaxis: y3
    mode: lines
    show_value: true
    line:
      shape: line
      color: blue
      width: 1
  - entity: sensor.eu08l_buffer1_actual_low_temperature
    name: Pufferspeicher Mitte
    yaxis: y4
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_boil1_set_temperature
    name: Temperatur Soll
    yaxis: y5
    mode: lines
    show_value: true
    line:
      shape: line
      color: cyan
      width: 1
  - entity: sensor.eu08l_boil1_actual_high_temperature
    name: Temperatur Oben
    yaxis: y5
    mode: lines
    show_value: true
    line:
      shape: line
      color: red
      width: 1
  - entity: sensor.eu08l_hp1_inverter_power_consumption
    name: Leistung [W]
    yaxis: y6
    mode: lines
    show_value: true
    line:
      shape: line
      color: green
      width: 1
hours_to_show: 168
refresh_interval: 10
title: Heizung
layout:
  height: 1000
  margin:
    l: 100
  grid:
    rows: 6
    columns: 1
    roworder: top to bottom
    ygap: 0.25
    pattern: coupled
  yaxis:
    tickangle: 45
    title: ""
    showgrid: true
    fillcolor: rgba(0, 0, 220, 0.5)
  xaxis:
    categoryorder: array
    categoryarray:
      - Standby
      - Central Heating
      - Domestic Hot Water
      - Cold Climate
      - Circulate
      - Defrost
      - "Off"
      - Frost
      - Standby-Frost
      - Not used
      - Summer
      - Holiday
      - Error
      - Warning
      - Info-Message
      - Time-Block
      - Release-Block
      - Mintemp-Block
      - Firmware-Download
  yaxis2:
    title: °C
    showgrid: true
  yaxis3:
    range:
      - 9
      - 61
    showgrid: true
    title: °C
  yaxis4:
    range:
      - 20
      - 35
    showgrid: true
    title: °C
  yaxis5:
    range:
      - 39
      - 61
    showgrid: true
    title: °C
  yaxis6:
    showgrid: true
    title: W
  annotations:
    - text: Req.-Type
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.8
      yref: y domain
      font:
        size: 14
    - text: Aussentemperetaur
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.1
      yref: y2 domain
      font:
        size: 14
    - text: Vorlauf- Rücklauf
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y3 domain
      font:
        size: 14
    - text: Puffer Speicher
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y4 domain
      font:
        size: 14
    - text: WW Speicher
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y5 domain
      font:
        size: 14
    - text: Leistung
      showarrow: false
      x: 0.5
      xref: paper
      "y": 1.2
      yref: y6 domain
      font:
        size: 14
defaults:
  yaxes:
    side: left
    overlaying: "y"
    visible: true
  xaxis:
    rangeselector:
      "y": 1.5
      buttons:
        - count: 1
          step: minute
        - count: 15
          step: minute
        - count: 1
          step: hour
        - count: 12
          step: hour
        - count: 1
          step: day
        - count: 7
          step: day

It’s possible to use an JSON or jaml file via include or something like this to make my cards/ topics smaller and clearer?

You put the filter in ambient temperature, didn’t you intend to put it inside operation state instead?

Also I suggest you take a look at the debugging section of the readme. That way you can see exactly what the data contains

Not to my knowledge unfortunately. Maybe with some other hacs component.
This for example: GitHub - iantrich/config-template-card: 📝 Templatable Lovelace Configurations

I’d be careful though, you may end up with yamls which are small but complicated and harder to maintain

@mateine
“you put the filter in ambient temperature” - you are right - I really apologize having you bothered with my mistake. It works now. Many thanks.

Also - I will have a look ate the debugging section of course!

Have a good day and many thanks again!
Rainer

1 Like

Hello experts,

From a newcommer:
I have a bar graph showing duration values in float (decimal time). How could I display them in “h:mm” format?

Many thanks.

Do the values represent hours, minutes, seconds or milliseconds?

They represent hours. E.g: 6,25 means 6h 15min

type: custom:plotly-graph
entities:
  - entity: sensor.openweathermap_temperature
    # by transforming it to dates, we can then use time formatting in layout/yaxis/tickformat
    filters:
      - map_y: new Date(+y * 1000 * 60 * 60)
  - entity: sensor.openweathermap_temperature
    # this one is here just for you to confirm the data is mapped correctly.
    # Delete it once confirmed
    opacity: 0.3
    line:
      width: 5
    yaxis: y2
hours_to_show: 24
layout:
  yaxis:
    tickformat: '%H:%M'

Unfortunatelly it’s not working.
It doesn’t show me any value now.

My code:

type: custom:plotly-graph
title: Time
hours_to_show: 1M
entities:
  - entity: sensor.time_total
    name: Time
    statistic: sum
    unit_of_measurement: h
    filters:
      - delta: null
        map_y: new Date(+y * 1000 * 60 * 60)
    period:
      7d: day
      1M: week
      1y: month
    type: bar
    marker:
      color: rgba(65,105,225,0.9)
layout:
  height: 400
  dragmode: pan
  yaxis:
    fixedrange: true
    tickformat: "%H:%M"
  xaxis:
    rangeselector:
      "y": 1.2
      buttons:
        - count: 7
          step: day
        - count: 1
          step: month
        - count: 1
          step: year

25-11-2024_13-01-08