Plotly interactive Graph Card

Nice card!
I’m in the process of migrating my apexcharts cards to plotly and spent too much time on one issue. How do I apply smoothing filters and use show_value at the same time? The show_value always gets distorted by the filters and I would really like it to show the actual current value of the sensor.
Thanks in advance!

You could readd the real last known point at the end:

filters:
 - fn: ({ys, vars}) => vars.last = ys.at(-1)
 - ...smoothing...
 - fn: ({xs,ys,vars}) => ({xs: [...xs, Date.now()], ys: [...ys, vars.last]})

Otherwise you can have the entity twice but only use the last point of the second one and then group them

1 Like

hi, I’m experiencing a strange behavior with the scrolling buttons.
I have this chart that shows the daily values of how long the boiler was on, month by month.
Initially, the values are displayed correctly, but when I scroll to the previous month using the scroll button, I see very thin bars.
However, if I keep going back to the beginning of the data, the chart goes back to normal, and if I then scroll forward through the months, I can see all the values properly.


type: custom:plotly-graph
title: Giornaliero
entities:
  - entity: sensor.time_on_caldaia_g
    name: Accensione Giornaliera Caldaia
    statistic: state
    period: day
    type: bar
    texttemplate: "%{y:.2f}"
    textfont:
      color: white
    marker:
      color: rgba(66,105,208,0.7)
hours_to_show: current_month
fn: |
  $fn({getFromConfig, vars}) => {
    const range = getFromConfig("visible_range");
    const width = range[1] - range[0];
    vars.xrange = (h) => {
      if (h === null) h = (width)/1000/60/59;
      let start = new Date((range[0] + range[1])/2.0);
      start.setHours(12, 0, 0, 0);
      if (h >= 24*7) start.setFullYear(start.getFullYear(), start.getMonth(), start.getDate()-start.getDay());
      if (h >= 24*30) start.setDate(0);
      if (h >= 24*365) start.setMonth(0);
      return [start.getTime(), start.getTime() + 1000*60*60*h];
    }
    vars.scroll = (label, p) => ({
      args: [
        {
          layout: {
            "xaxis.range": [range[0] + width*p, range[1] + width*p],
          }
        }, {
          transition: {
            duration: 150,
          }
        }
      ],
      label,
      method: "animate",
    })
    
    vars.zoom = (label, h) => ({
      args: [
        {
          layout: {  
            "xaxis.range": vars.xrange(h),
          }
        }
      ],
      label,
      method: "animate",
    })
  }
layout:
  barcornerradius: 30%
  plot_bgcolor: black
  height: 390
  margin:
    r: 10
    l: 40
    b: 70
    t: 40
  xaxis:
    range: $fn({vars}) => vars.xrange(null)
    tickangle: -45
    tickformat: "%d %b"
    nticks: 20
    fixedrange: true
    gridcolor: rgba(238,235,235,0.3)
  yaxis:
    fixedrange: true
    gridcolor: rgba(238,235,235,0.3)
  updatemenus:
    - buttons:
        - $fn({vars}) => vars.scroll( '<', -1.0)
        - $fn({vars}) => vars.scroll( '>', 1.0)
      direction: right
      active: -1
      pad:
        t: -40
        r: 1
      type: buttons
      xanchor: right
      x: 1

can someone help me?
thanks

Try with:

filters:
  - filter: i>0

The issue is that home assistant “invents” a data point at the beginning of the requested intervl, and plotlyjs sees that the distance between the first and following data points is very short so it makes skinny bars

1 Like

Thanks, now it works better, but i miss the first day of the month. any suggestion?

Try with

time_offset: -1m

Bar charts are as you see a bit quirky because of these details.

Instead of filtering and offsetting, you could also use the resample filter which would force the data points to be evenly spaced

2 Likes

It works with

time_offset: 1m

Hi.
I am wanting to make that same graph, but I have solar panels, so the hourly energy can go up or down. I would like the bars to stay with the last value of each hour (it is what I pay or sell).
Would you know how I can change it? If I use “period: hour” as it is, it makes me the average, and “max” or “min” is not useful either because they are not the values I am looking for.
“statistic: state” doesn’t work for my (leaves the graph blank).
Thanks.

Hi, its the first time I try Plotly and unfortunately I can’t get subplots up and running. I want the last series to be in a second plot, but it is always overlayed. My guess is I’m missing only a small config piece?

type: custom:plotly-graph
entities:
  - entity: sensor.inverter_grid_power
    name: Netz
    line:
      color: Indigo
    filters:
      - multiply: -1
      - resample: 1m
    hovertemplate: <br><i>%{y} W</i>
    yaxis: "y"
  - entity: sensor.inverter_load_power
    name: Verbrauch
    line:
      width: 0
    fill: tozeroy
    fillgradient:
      start: 0
      stop: 4000
      type: vertical
      colorscale:
        - - 0
          - rgba(50, 175, 0, 0.6)
        - - 0.5
          - rgba(240, 175, 0, 0.6)
        - - 1
          - rgba(240, 0, 0, 0.6)
    filters:
      - resample: 1m
    hovertemplate: <br><i>%{y} W</i>
    yaxis: "y"
  - entity: sensor.inverter_battery_power
    name: Batterie
    line:
      color: DarkCyan
      width: 1
    filters:
      - multiply: -1
      - resample: 1m
    hovertemplate: <br><i>%{y} W</i>
    yaxis: "y"
  - entity: sensor.inverter_pv_power
    name: PV
    line:
      color: Gold
    filters:
      - resample: 1m
    hovertemplate: <br><i>%{y} W</i>
    yaxis: "y"
  - entity: sensor.inverter_battery
    name: Batteriestand
    filters:
      - resample: 1m
    yaxis: y2
hours_to_show: 24
refresh_interval: 10
layout:
  hovermode: x unified
  grid:
    rows: 2
    columns: 1
    pattern: coupled
    roworder: top to bottom

Try adding:

defaults:
  yaxes:
    side: left
    overlaying: false
    visible: true
    showgrid: true

Thanks a lot!

Unfortunately I have another one :frowning: What determines the order of the charts? I would like the smaller graph below, but changing the yaxis or the domain didn’t work for me.

Hello,

I would like to create a bar graph, in this case of energy production. The bars shows the energy production per month and the month of several years are shown next to each other.
Compare the energy production by month is than easy.
See example below.

type: custom:plotly-graph
entities:
  - entity: sensor.solaredge_lifetime_energy
    texttemplate: "%{y}"
    type: bar
    statistic: sum
    period: month
    filters:
      - delta
hours_to_show: 2y
refresh_interval: 100
Layout:
  width: 500
grid_options:
  columns: full

Is this possible with the Plotly graph?

It is possible, see:

Ok,
Is it correct that each year must be an entity? Like in the enclosed yaml

type: custom:plotly-graph
entities:
  - entity: ""
    name: Now
    yaxis: y9
    showlegend: false
    line:
      width: 1
      dash: dot
      color: deepskyblue
    x: $ex [Date.now(), Date.now()]
    "y":
      - 0
      - 1
  - entity: sensor.solaredge_lifetime_energy
    name: 2023
    texttemplate: "%{y}"
    type: bar
    statistic: sum
    period: month
    time_offset: 2y
    filters:
      - delta
  - entity: sensor.solaredge_lifetime_energy
    name: 2024
    texttemplate: "%{y}"
    type: bar
    statistic: sum
    period: month
    time_offset: 1y
    filters:
      - delta
  - entity: sensor.solaredge_lifetime_energy
    name: 2025
    texttemplate: "%{y}"
    type: bar
    statistic: sum
    period: month
    time_offset: 0y
    filters:
      - delta
hours_to_show: 1y
refresh_interval: 100
layout:
  barmode: group
#  paper_bgcolor: rgba(0,0,0,0)
  plot_bgcolor: rgba(0,0,0,0)
  xaxis:
    tickformat: "%b "
  height: 500
  #barcornerradius: 15
  bargap: 0.5
  bargroupgap: 1
grid_options:
  columns: full

When doing this the bars are very narrow. How can I make them wider?

Exactly! Look in the links to avoid overlap.
Also you may prefer to use

hours_to_show: current_year

Instead of just 1y

I am trying to just make a simple scatter plot. I couldn’t get any sensors to plot so I just started to see if I could get some hard coded data to plot. Here is my code

type: custom:plotly-graph
title: Room vs Outdoor Temperature (Working Test)
entities:
  - entity: sensor.blank_blank
  - entity: ''
    type: custom
    data:
      type: scatter
      mode: markers
      name: Test Dots
      x: [19.5, 20.0, 21.0]
      y: [18.0, 18.5, 19.0]
      marker:
        color: red
        size: 10
layout:
  xaxis:
    title: Room Temperature (°C)
    type: linear
    range: [18, 22]
  yaxis:
    title: Outdoor Temperature (°C)
    type: linear
    range: [17, 20]

but it leaves a blank graph. Any help or insight is appreciated.

Syntax is quite wrong.
See the readme, examples and the yaml validation tool.

I assume you are copy pasting from an AI, you can give it a hand pasting examples from the readme & links

When using a stack group is there a way to see the SUM total of the stack group when mousing over the top in addition to seeing the top most items amount in the group?

Hello mateine,
fantastic integration! I’m quite new to home assistant and plotly, and spent the last evenings fiddling with diagrams for solar production/consumption etc.
I am quite very happy with the result (see screenshot) but I’m struggling with a way to get those graphs to show yesterday and before. The buttons you see at the very top currently do nothing but ideally I’d use them to cycle through the days. Could you point me into the right direction?
(Asked AI but the suggestions didn’t work)

Try with this approach:

1 Like