Black Lives Matter. Please consider donating to Black Girls Code today.

Overlays on x-axis

Hi there

We’re using plotly for other charts on this application so I’ll tried to achieve following with plotly:
events_and_trips

What I try to do is to display “Events” on the top and “Trips” at the bottom of the chart.
E.g. a trip is exactly at 19:14 (Time) and I need to place it on the chart at 19:14.

Is something like that possible? I tried to use multiple x-axis (even y-axis) but the problem is that they’re “dependend” on the other axis and “move them”.

Hi @optenag,

To define a plot like in your image, you should find a method to work with datetimes in plotly.js (you selected this category to address your question).

I was able to generate such a plot in Python. For each x-list I defined two versions: one as a list of datetimes and another as the representative time strings to be displayed on hover. This is the code:

import plotly.graph_objects as go
import numpy as np
from datetime import datetime


mytime= [datetime(2020,2, 10, 8, 0, 0 ),
         datetime(2020,2, 10, 8, 30, 0 ),
         datetime(2020,2, 10, 9, 0, 0 ),
         datetime(2020,2, 10, 9, 30, 0 ), 
         datetime(2020,2, 10, 10, 0, 0 ), 
         datetime(2020,2, 10, 10, 30, 0 )]

mytime_string =[t.strftime("%H:%M") for t in mytime]

event_time = [datetime(2020,2, 10, 8, 15, 0 ), 
              datetime(2020,2, 10, 9, 40, 0 ),
              datetime(2020,2, 10, 10, 20 , 0 )]
event_string= [t.strftime("%H:%M") for t in event_time]

trip_time = [datetime(2020,2, 10, 8, 15, 0 ), 
             datetime(2020,2, 10, 9, 25, 0 ),
             datetime(2020,2, 10, 10,0 , 0 )]

trip_string =[t.strftime("%H:%M") for t in trip_time]

y= [200, 250, 175, 250, 280, 210]
ymax =max(y) + 0.25

h=3  #this variable controls the position of event respectively trip  marker
fig = go.Figure(go.Scatter(x=mytime, 
                           y=y, 
                           mode='lines', 
                           line_width=2,
                           customdata=mytime_string,
                           hovertemplate = "Time: %{customdata}<br>y: %{y}<extra></extra>"))


fig.add_scatter(x=event_time, 
                y =[ymax-h]*3,
                mode='markers', 
                marker= dict(symbol='triangle-up',
                             size=16, 
                             color='red'
                             ),
                customdata = event_string,
                hovertemplate = "Event: %{customdata}<extra></extra>",
                name='event')


fig.add_scatter(x=trip_time, 
                y =[150+h]*3,
                mode='markers', 
                marker= dict(symbol='triangle-down',
                             size=16, #[0, 16, 0, 16,0, 16],
                             color='green'), 
                customdata = trip_string,
                hovertemplate = "Trip: %{customdata}<extra></extra>",
                name='trip')             
                             
fig.update_layout(width=700, height=500,
                  legend_itemsizing='trace',
                  yaxis_range=[150,ymax],
                  xaxis_range= [datetime(2020,2, 10, 8, 0, 0 ), datetime(2020,2, 10, 10, 30, 0 )])
                 

and the corresponding Figure:

For an easier translation to plotly.js I post here the figure description in a json format:

{
  "data": [
    {
      "customdata": [
        "08:00",
        "08:30",
        "09:00",
        "09:30",
        "10:00",
        "10:30"
      ],
      "hovertemplate": "Time: %{customdata}<br>y: %{y}<extra></extra>",
      "line": {
        "width": 2
      },
      "mode": "lines",
      "type": "scatter",
      "x": [
        "2020-02-10T08:00:00",
        "2020-02-10T08:30:00",
        "2020-02-10T09:00:00",
        "2020-02-10T09:30:00",
        "2020-02-10T10:00:00",
        "2020-02-10T10:30:00"
      ],
      "y": [
        200,
        250,
        175,
        250,
        280,
        210
      ]
    },
    {
      "customdata": [
        "08:15",
        "09:40",
        "10:20"
      ],
      "hovertemplate": "Event: %{customdata}<extra></extra>",
      "marker": {
        "color": "red",
        "size": 16,
        "symbol": "triangle-up"
      },
      "mode": "markers",
      "name": "event",
      "type": "scatter",
      "x": [
        "2020-02-10T08:15:00",
        "2020-02-10T09:40:00",
        "2020-02-10T10:20:00"
      ],
      "y": [
        277.25,
        277.25,
        277.25
      ]
    },
    {
      "customdata": [
        "08:15",
        "09:25",
        "10:00"
      ],
      "hovertemplate": "Trip: %{customdata}<extra></extra>",
      "marker": {
        "color": "green",
        "size": 16,
        "symbol": "triangle-down"
      },
      "mode": "markers",
      "name": "trip",
      "type": "scatter",
      "x": [
        "2020-02-10T08:15:00",
        "2020-02-10T09:25:00",
        "2020-02-10T10:00:00"
      ],
      "y": [
        153,
        153,
        153
      ]
    }
  ],
  "layout": {
    "height": 500,
    "legend": {
      "itemsizing": "trace"
    },
    "width": 700,
    "xaxis": {
      "range": [
        "2020-02-10T08:00:00",
        "2020-02-10T10:30:00"
      ]
    },
    "yaxis": {
      "range": [
        150,
        280.25
      ]
    }
  }
}

Comparing the two versions, python and json, one can see how datetime(s) have been translated to strings.
You need to find out the equivalent of these datetime(s) in plotly.js.

Searching related plotly.js QA on this forum I stumbled upon an example on how to set the xaxis range as datetime:

[plotly.js: Set range on xaxis with dates](plotly.js: Set range on xaxis with dates)
Maybe this example can suggest how to implement in plotly.js the above python code.

Hi @empet

Thank you very much, that helped me a lot!
I’ll try to convert it to JS but that should be easy :+1: