Plotly interactive Graph Card

The only way to find out is to analyze the raw data and look at the yaml. I suggest you open an issue in the repo and post as much info as you can there (it’s easier to follow up than here)

This is interessting. I tried to set this up myself but somehow the card displays not the right values. Could you might be post the code as a code block with correct formating. The indents/formatting in your post is broken.

Thank you :slight_smile:

type: custom:plotly-graph
time_offset: 0.5d
entities:
  - entity: sensor.measured_temperature
    name: Measured Temperature
    line:
      color: orange
      width: 2.5
    filters:
      - store_var: temperature
  - entity: sensor.p_hotwater_forecast_model
    showlegend: false
    name: Forecasted Temperature
    line:
      color: red
      dash: dot
      width: 2
    unit_of_measurement: °C
    filters:
      - fn: |-
          ({ meta, vars }) => ({
            xs: [vars.temperature_eau.xs.slice(-1)[0],...meta.scheduled_forecast.map(({ date }) => new Date(date))],
            ys: [vars.temperature_eau.ys.slice(-1)[0],...meta.scheduled_forecast.map(({ p_HotWater_forecast_model }) => p_HotWater_forecast_model)],
          })
  - entity: sensor.p_hotwater_forecast_model
    name: Forecasted Temperature
    line:
      width: 3
      color: red
  - entity: ''
    name: Now
    yaxis: y9
    showlegend: false
    line:
      width: 1.5
      dash: dot
      color: black
    x: $ex [Date.now(), Date.now()]
    'y':
      - 0
      - 1
defaults:
  entity:
    show_value: false
    line:
      shape: spline
layout:
  legend:
    itemwidth: 10
hours_to_show: 48

very generic question - but hoping to find out before i jump in head first trying to do something that might not be possible.

i want to display the state-history of a binary sensor just like the history card - but day by day rather than for the last 24 hours. essentially like the sure petcare app does for the outside time for a cat (not neccesarily and actually preferably, not vertically like this):


is this even possible with this card?

i already have this with the apexcharts card, but this only calculates a total sum day by day.
image

Oh wow, that’s quite a challenge. Plotly doesn’t have a chart type for this, so the only way I can think of to “simulate” this is through a hack: using multiple stacked bar charts, where every second one has a transparent color and all the data is computed via JavaScript ($ex or $fn)

  1. Add an entity that fetches the data, but is marked as “internal”, computes the start and end time of each vertical bar and stores everything in a var.
  2. Add n traces that fetch no data but look at the stored var. Every second trace will be transparent and represent the gaps
  3. Configure the y axis so it can represent time of day

If you understand JavaScript and are reasonably well versed in algorithms, by all means read the readme, give it a try and post back the results! (Preferably in a Show&Tell post in the Discussions section of the repo.

If your hope was to achieve this using pure yaml, I’ll have to disappoint you.
Good luck!

I knew i would have to learn quite a bit, so a challenge was expected :slight_smile:

Ill give it a whirl, was just hoping that maybe someone had some sort of starting point that was similar :slight_smile:

Thanks for the ideas

Cool! Feel free to open a Q&A topic in the repo if you need help along the way

It also happens wihout scrolling… But scrolling also has affect on which bars are missing.

I think it is a reincarnation of this Data returned from Recorder for statistics is inconsistent between queries because the start time state is always included · Issue #88696 · home-assistant/core · GitHub

Is it possible to enlarge the graph by clicking on it like on the stock sensor card?

There’s a way but it is very hard abd hacky. So basically no

I have a utility meter being graphed by Plotly and with a PERIOD of HOUR.

The latest hour shown is doubled-up.

Is there anything I can do to fix this?

Thank you.

Try removing show_value from the defaults (at the bottom of the yaml). It’s not compatible with bar graphs and I think it is creating that artifact

2 Likes

Wow!

That did it.

Thank you so much.

Glad to hear!
show_value actually creates a new trace with no legend and only the last datapoint. It copies all other settings from the original trace, except that they mode is set to text+marker. In bar graphs, the whole thing doesn’t make much sense so you got that artifact

I have a graph of electric use over time and I would like to add a binary sensor that shows when the furnace is running (i.e., calling for heat).

It works, but looks quite bad.

Is there a way to show this data so I can match up electric use with furnace operation?

Thank you.

Here is what I have now:

Here’s the code:

type: custom:plotly-graph
defaults:
  entity:
    show_value: true
entities:
  - entity: sensor.630_123_1min
    name: |
      $ex meta.friendly_name + " " + Math.round(ys[ys.length - 1])
    statistic: mean
    period: 5minute
    yaxis: y2
    line:
      color: black
  - entity: binary_sensor.630_heat_graph_binary
    name: |
      $ex meta.friendly_name
    opacity: 0.4
layout:
  height: 600
  xaxis:
    rangeselector:
      'y': 1.25
      buttons:
        - count: 1
          step: hour
        - count: 12
          step: hour
        - count: 96
          step: hour
  yaxis:
    fixedrange: true
    range:
      - 40
      - 100
  yaxis2:
    fixedrange: true
    range:
      - 1
      - 4000
refresh_interval: 60
hours_to_show: 24
title: 630
view_layout:
  column: 1

And here is the configuration.yaml code that creates the binary sensor:

  - binary_sensor:
      - name: 630 Heat Graph Binary
        state: "{{ is_state_attr('climate.630', 'hvac_action','heating') }}"

Try fixing both range and domain for yaxis3 too:

layout:
  yaxis3:
    domain: # this is the % of the y axis height 
      - 0.1
      - 0.5
    categoryorder: array
    categoryarray: # set it here to ensure "false" is always under. Otherwise plotly will invert the order depending on what it sees first
      - false
      - true

Thank you very much for the help.

I’m still trying to figure out how to use your code to put the y3 axis data at the correct height, but luckily for now it is draggable.

But the bigger issue is that the overlaying of a bar (on/off state) on a line (watts being used) is clunky looking. I was hoping there was a nice way.

Here’s what I’ve got so far.

Oh, I see what you mean. A better way of visualizing this is to use the binary entity to either fill or not another trace.
This is more involved:

  • you need to resample the other sensor (see filters)
  • store the datapoints in a variable (see store_var)
  • Then add the binary entity and also resample it
  • Then in a map filter, for each index you either show the value of the other sensor, or null (depending on the value of the binary one)
  • And finally style the result using fill: tozeroy, and maybe hiding it’s legend or merging both legends using legendgroup.

If you need help, feel free to make a post in the Q&A section of “Discussions” inside the repo and I’ll help you out with the yaml

Hi. First of all, I would like to say, this is a really nice card. Congratuations and thanks. I really like the high level of customization. But unfortunately I’m not so familiar with javascript.
I created a pretty simple chart, but I’m still struggling with some things.
Simple and stupid question: how can I read the Y axis values for date_from and
date_to in the following code?

fn: |
  $fn({getFromConfig, vars})=> {
    const range = getFromConfig("visible_range");
    const width = range[1] - range[0];
    const date_from = new Date(getFromConfig('visible_range')[0]);
    const date_to = new Date(getFromConfig('visible_range')[1]);