Bring Drag & Drop to Dash with Dashboard Engine. 💫 Learn how at our next webinar!

Plotting time/dates on a log axis?

Hi all

Is it possible to plot dates or time on a log axis in Plotly?

Trying to achieve something like this:

I have tried the usual:

xaxis= dict(

But it’s not plotting anything and my axis values look like this rather than what I’m expecting in my screenshot above.



Hi @Chris369, could you please give an example of code reproducing what you want to do? On a log-axis, if the dates are from 2011 to 2020 then the axis spacing will not be very different from a linear one since their differences are very small compared to their value. On the other hand, for dates spanning more range on a log-axis, I tried the following which works ok

import plotly.graph_objects as go
x = [1000, 2011, 2012, 2013, 2050, 2100]
y = [0.5, 1, 2, 3, 4, 5]
fig = go.Figure(go.Scatter(x=x, y=y))

Please share more code if you cannot find a solution.

Hi Emmanuelle

Thanks for the reply. Your x values are integers that happen to represent years though and I want to use x values that are of type datetime e.g.

2010-09-01 00:00:00

2010-09-02 00:00:00

2010-09-03 00:00:00

2010-09-04 00:00:00

2010-09-05 00:00:00

2019-12-25 00:00:00

2019-12-26 00:00:00

2019-12-27 00:00:00

2019-12-28 00:00:00

2019-12-29 00:00:00

2019-12-30 00:00:00

2019-12-31 00:00:00

With data like this as my x values and a log scale I’m getting weird labels with % (see my second screenshot) and no line is being plotted. If I change back to non-log it plots fine (with a normal looking time series labels and plot line).

Anyone else? Is this possible?

My plot with a non log x-axis works fine e.g.

By changing to 'type=‘log’ I’m wanting my x-axis to squash up like this:

But I’m getting this:

an axis type can be "linear" | "log" | "date" | "category" | "multicategory" (see but cannot combine date and log. What you can do is transform your dates to numerical values (using for example and set ticks manually to format them as dates (

However, if you really want to squash your axis using a log scale will not be enough, you would need to remove a value close to the initial value for example.

ok thanks - have tried this and my plot is now appearing but my tick labels are 1.3b, 1.32b etc (the float version of the date time), even though I have set tick text as follows:

x2 = [datetime.timestamp(x) for x in x1]
x_tick_text = [datetime.fromtimestamp(x) for x in x2]
x_tick_values = [x for x in x2]
xaxis= dict(
                tickmode = 'array',


But you are right - the log scale is not looking as I was after and looks exactly the same as a linear scale. What do you mean by this?

you would need to remove a value close to the initial value for example.

1 Like

Hi Chris,

I’ve followed Emmanuelle’s advice, i.e. “transform your dates to numerical values and set ticks manually to format them as dates” and that did the trick:

The below code is not perfect but does work:

@app.callback(Output('yield-curves-graph', 'figure'),
             [Input('memory-storage', 'data')])
def updateYieldCurvesFigure(selectedYieldCurveNames):

    if selectedYieldCurveNames is None:
        raise PreventUpdate

    rates = dict()

    savedDataframe = pd.read_csv(DATA_PATH.joinpath("yield_curve.csv"))

    for selectedYieldCurveName in selectedYieldCurveNames:
        workingDataframe = savedDataframe.copy()
        workingDataframe = workingDataframe[workingDataframe['y'] == selectedYieldCurveName]
        del workingDataframe["x"]
        del workingDataframe["y"]
        rates[selectedYieldCurveName] = workingDataframe.iloc[0]

    shifts = [
        {'1 month': 30},
        {'3 months': 30 * 3},
        {'6 months': 30 * 6},
        {'1 year': 365},
        {'2 years': 365 * 2},
        {'3 years': 365 * 3},
        {'5 years': 365 * 5},
        {'7 years': 365 * 7},
        {'10 years': 365 * 10},
        {'20 years': 365 * 20},
        {'30 years': 365 * 30}

    timestamp = 0
    now = datetime.fromtimestamp(timestamp)

    timestamps = list()
    labels = list()

    for shift in shifts:
        key = shift.keys()[0]
        value = shift.values()[0]
        date = now + timedelta(days=value)
        timestamp = time.mktime(date.timetuple())

    yieldCurvesFigure = {
        'data': [
            ) for selectedYieldCurveName in selectedYieldCurveNames
        'layout': dict(
                title='Treasury yields (%)'
            margin={'l': 50, 'b': 60, 't': 10, 'r': 20},
            legend={'x': 1, 'y': 1},

    return yieldCurvesFigure

Good luck.