Timezone of datetimes not being reflected in bar graphs

I can create a bar graph in Dash using datetimes on the x-axis, but when the datetimes have a non-UTC timezone attribute the bar graph shows them as though they were in UTC anyway. Is there a way to force the app to recognize the timezone? I have included a basic example below. There is a loop that adds in a timezone but if you comment out the loop it makes no difference to the resultant app.

import dash
import dash_core_components as dcc
import dash_html_components as html

from datetime import datetime
import timezonefinder, pytz

tf = timezonefinder.TimezoneFinder()
utc = pytz.utc

x=[datetime(2012, 4, 21, 2, tzinfo=utc), 
   datetime(2012, 4, 21, 3, tzinfo=utc), 
   datetime(2012, 4, 21, 5, tzinfo=utc)]

#commenting this loop out makes no difference
for i in range(0,3):
    x[i]=x[i].astimezone(pytz.timezone('Australia/Sydney'))

app = dash.Dash()

figure = {
    'data': [{
        'x': x,
        'y': [1, 3, 2],
        'type': 'bar'
    }],
    'layout': {}
}

app.layout = html.Div([
    html.H3('Test Dates'),

    dcc.Graph(
        id='my-graph',
        figure=figure
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)

I am hitting this too. After digging in the sourcecode I have deployed this patch in my code. Ugly as hell and only tested in Python 3, but I hope it is useful to you:

import plotly.utils

# Subclass doesn't work because "encode()" calls a hardwired class. I would need
# to overload too many methods.
# So, Hardcore MonkeyPatching of the original class.
# BEWARE: All data displayed should be in the same timezone.
# BEWARE: I don't know what would happen if the data crosses a DST change.
# BEWARE: I don't care about performance for now.
@staticmethod
def encode_as_datetime(obj):
    if not isinstance(obj, datetime.datetime):
        raise plotly.utils.NotEncodable
    return obj.strftime('%Y-%m-%d %H:%M:%S')

# MonkeyPatching
plotly.utils.PlotlyJSONEncoder.encode_as_datetime = encode_as_datetime

Thanks @jcea, I ended up not using timezones and just made manual adjustments to the datetimes. Good to see a solution though.

It’s pretty sad that this is the only way of showing data in your own timezone…

Update: as of plotly 4.0, datetime objects with timezone info (non UTC) are not converted to UTC in plotly figures, but left unchanged. See https://github.com/plotly/plotly.py/pull/1581

import plotly.graph_objs as go
import pandas as pd
import sys, datetime

x1 = pd.to_datetime(
        ['2015-04-04 12:00:00', '2015-04-04 13:00:00', '2015-04-04 15:00:00'])
x2 = x1.tz_localize('UTC').tz_convert('US/Eastern')

fig1 = go.Figure(data=[go.Scatter(x=x2, y=[1, 3, 2])])
fig1.show()

1 Like