Plotly interactive Graph Card

Thanks - based on this example I was able to calculate the daily COP of my heatpump like this:

type: custom:plotly-graph
column_span: 2
hours_to_show: 720
layout:
  height: 900
  xaxis:
    rangeselector:
      "y": 1.25
      buttons:
        - count: 1
          step: day
        - count: 7
          step: day
        - count: 1
          step: month
        - count: 1
          step: year
entities:
  - entity: sensor.esp32_heating_totalheat
    statistic: state
    name: Erzeugte Wärme
    internal: true
    filters:
      - resample: 1d
      - delta
      - map_y: parseFloat(y)
      - store_var: totalheat
  - entity: sensor.shelly_heatpump_total_active_energy
    statistic: state
    name: Verbrauchter Strom Heizung
    internal: true
    filters:
      - resample: 1d
      - delta
      - map_y: parseFloat(y)
  - entity: sensor.shelly_heatpump_total_active_energy
    statistic: state
    name: COP WMZ + Shelly
    type: bar
    unit_of_measurement: x
    filters:
      - resample: 1d
      - delta
      - map_y: parseFloat(y)
      - map_y: vars.totalheat.ys[i] / y;

One more question: I want to switch between e.g. the daily and the monthly COP, I need different resample intervals (1 day / 1 month), based on the selected range. Like period: auto for statistics.

Can I do this with one plotly graph with a variable range, or do I need two different graphs - one for daily, one for monthly?

Cool filters use!

You could try making it a $ex that depend on the width of the visible x range.

$ex +get('visible_range')[1] - +get('visible_range')[0] > 1000*60*60*24 *7 ? "day" : "hour"

Thx! Could you provide an example of $ex that uses the width of the visible x range (as a timespan, not in pixel or so), combined with an if? Or a link to an explanation of the $ex?

That’s exactly what I shared (untested)

Sorry, where did share this? I only saw the link to the “Compute absolute humidity example” above, which doesn’t have a $ex.

oh sorry, i had misformatted it and it wasn’t being shown. fixed now two posts above

You can put that in a var and use it in other $ex to change things like period, the resample parameter, etc

With your formular I got it to work, thx!

Great! Don’t forget to share a snippet of your code for the next person :slight_smile:

Great! Don’t forget to share a snippet of your code for the next person :slight_smile:

I still have some troubles with how the data are shown, I’ll wait until I have at least some months data and post then if it works (and also if it does not work :wink: )

Hello,
I would need some help.
I have this graph:


I’m ploting my pv forecast against my hourly pv production
I would like to get rid of the 0 values on the pv production graph I’m using a utility meter that resets hourly. Is there a way to smooth this out?
Here is the code:

type: custom:plotly-graph
view_layout:
  grid-area: solar
hours_to_show: 1d
time_offset: 0h
refresh_interval: 30
entities:
  - entity: sensor.pv_hourly
    name: Solar Power
    line:
      color: rgb(255, 155, 48)
      shape: spline
      width: 1
    fill: tozeroy
    fillcolor: rgba(255, 155, 48, 0.3)
    yaxis: y1
    show_value: false
    showlegend: false
  - entity: sensor.meteo_forecast_today_sum
    line:
      color: rgb(125,125,125)
      shape: spline
    fill: tozeroy
    filters:
      - fn: |
          ({meta}) => {
            const entries = meta.watts.map(item => Object.entries(item)[0]); 
            const xs = entries.map(([start, _]) => new Date(start)); 
            const ys = entries.map(([_, value]) => value/1000); 
            return { xs, ys };
          }
    yaxis: y1
    showlegend: true
  - entity: sensor.meteo_forecast_tomorrow_sum
    line:
      color: rgb(90,90,90)
      shape: spline
    fill: tozeroy
    filters:
      - fn: |
          ({meta}) => {
            const entries = meta.watts.map(item => Object.entries(item)[0]); 
            const xs = entries.map(([start, _]) => new Date(start)); 
            const ys = entries.map(([_, value]) => value/1000); 
            return { xs, ys };
          }
    yaxis: y1
    showlegend: true
  - entity: sensor.meteo_forecast_day3_sum
    line:
      color: rgb(50,50,50)
      shape: spline
    fill: tozeroy
    filters:
      - fn: |
          ({meta}) => {
            const entries = meta.watts.map(item => Object.entries(item)[0]); 
            const xs = entries.map(([start, _]) => new Date(start)); 
            const ys = entries.map(([_, value]) => value/1000); 
            return { xs, ys };
          }
    yaxis: y1
    showlegend: true
  - entity: ""
    name: Now
    yaxis: y3
    showlegend: false
    line:
      width: 2
      dash: dot
      color: aqua
    x: $ex [Date.now(), Date.now()]
    "y":
      - 0
      - 1
defaults:
  yaxes:
    range:
      - 0
      - 1.4
    fixedrange: true
layout:
  height: 410
  margin:
    t: 55
    l: 50
  showlegend: false
  legend:
    x: 0.1
    "y": -0.8
  yaxis2:
    range:
      - 0
      - 1
    fixedrange: false
  xaxis:
    range: >-
      $ex [ new Date(new Date().setHours(6, 0, 0, 0)).getTime(), new Date(new
      Date().setHours(20, 0, 0, 0)).getTime() ]
    fixedrange: false
  annotations:
    - text: |-
        $fn ({hass}) =>
          "<span style='font-size: 24px;'><span style='color: orange'>"
          + Number(hass.states['sensor.meteo_forecast_today_sum'].state).toFixed(1) + "</span></span>kWh<br>"
          +  "</span><span style=''>Forecast Today</span><br>"
      xref: x domain
      yref: y domain
      xanchor: center
      yanchor: center
      x: 0.06
      "y": 1.2
      showarrow: false
    - text: |-
        $fn ({hass}) =>
          "<span style='font-size: 24px;'><span style='color: dodgerblue'>"
          + Number(hass.states['sensor.meteo_remaining_today'].state).toFixed(1) + "</span></span>kWh<br>"
          +  "</span><span style=''>Remaining</span><br>"
      xref: x domain
      yref: y domain
      xanchor: center
      yanchor: center
      x: 0.28
      "y": 1.2
      showarrow: false
    - text: |-
        $fn ({hass}) =>
          "<span style='font-size: 24px;'><span style='color: '>"
          + Number(hass.states['sensor.meteo_forecast_tomorrow_sum'].state).toFixed(1) + "</span></span>kWh<br>"
          +  "</span><span style=''>Forecast Tomorrow</span><br>"
      xref: x domain
      yref: y domain
      xanchor: center
      yanchor: centre
      x: 0.5
      "y": 1.2
      showarrow: false
    - text: |-
        $fn ({hass}) =>
          "<span style='font-size: 24px;'><span style='color: white'>"
          + Number(hass.states['sensor.meteo_forecast_day3_sum'].state).toFixed(1) + "</span></span>kWh<br>"
          +  "</span><span style=''>Forecast Day 3</span><br>"
      xref: x domain
      yref: y domain
      xanchor: center
      yanchor: center
      x: 0.72
      "y": 1.2
      showarrow: false
    - text: |-
        $fn ({hass}) =>
          "<span style='font-size: 24px;'><span style='color: red'>"
          + Number(hass.states['sensor.battery_state_of_charge'].state) + "</span></span>%<br>"
          +  "</span><span style=''>SOC</span><br>"
      xref: x domain
      yref: y domain
      xanchor: center
      yanchor: center
      x: 0.94
      "y": 1.2
      showarrow: false
config:
  scrollZoom: false

Oh that plot looks so good!

To remove the zeros you have 2 options:

  • custom function with $ex that finds the zeroes and accumulate since the last zero
  • clever filters use.

Since I’m feeling clever today, here’s the latter:

- entity: sensor.xyz
  filters: 
      - derivate
      - map_y: " y > 0 ? y : 0" # cap derivative to >0, so only accumulate upwards
      - integrate:
          reset_every: 1d # read resetting every day. 

Also would you post the plot and yaml here please? Sign in to GitHub · GitHub

This way it will make it to the image examples page so others can find your beautiful color scheme and layout.

Also 2:
I see you are using a fixed x range. Instead, you could use

hours_to_show: current_day

This way you would still be able to scroll it around to see previous days, and even use these Custom buttons to quick scroll to the next and previous day

Hello Forum,
I found this question here and tried to implement something similar for myself.
My aim is to display the temperature of my heating and at the same time color the graphs at the times when the oil burner is running:
grafik

I have tried the code from the link, unfortunately I get error messages and no result is visible.

Do you have any ideas on how I can implement this?
thanks
Henri

it looks fine except for the comment in line 24 that extends to line 25. Try removing it completely

image
Almost 400 stars in github! :tada:

Hey Mateine,

many thanks for your quick feedback. I think that my problem is somewhere else. I use the German client and add a Plotly Graph to my dashboard. If I copy your basic example, it works.

type: custom:plotly-graph
entities:
  - entity: sensor.uvr_tadesigner_t_puffer_o_wert
  - entity: sensor.status_olbrenner
    name: Brenner
hours_to_show: 24
refresh_interval: 10

But if I extend your example with additional options, the code seems to be wrong.

type: custom:plotly-graph
entities:
  - entity: sensor.uvr_tadesigner_t_puffer_o_wert
    internal: true
  - entity: sensor.status_olbrenner
    name: Brenner
hours_to_show: 24
refresh_interval: 10

The plot looks correct. The warning you see only means that the ui editor doesn’t support the advanced options (read the warning message)