Skip to content

Kaleido 1.0.0rc0 can't plot datetimes as axis label correctly when renderer=“png” #236

Closed

Description

@Honghe

Environment

  • Python 3.12
  • Plotly 6.0.0rc0
  • Kaleido 1.0.0rc0
  • vscode 1.96.0

Problem

in kaleido 1.0.0rc0, when set renderer="png", Plotly plot datetime as int as axis label, when set renderer="plot_mimetype", Plotly plot datetime correctly as axis label.
in Kaleido 0.2.1, no matter renderer="png" or renderer="plot_mimetype", Plotly can both plot datetime correctly as axis label.

import plotly.graph_objects as go
import pandas as pd

periods = 10
x = pd.date_range("20241215T00:00:00", periods=periods, freq="h").to_numpy()
y = list(range(periods))
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y))
fig.show(renderer="png")

Image

import plotly.graph_objects as go
import pandas as pd

periods = 10
x = pd.date_range("20241215T00:00:00", periods=periods, freq="h").to_numpy()
y = list(range(periods))
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y))
fig.show(renderer="plotly_mimetype")

Image

Temporarily workaround

my temporarily workaround is casting datetime to str dtype.

import plotly.graph_objects as go
import pandas as pd

periods = 1000
x = pd.date_range("20241215T00:00:00", periods=periods, freq="h")
y = list(range(periods))
fig = go.Figure()
fig.add_trace(
    go.Scatter(
        x=x.astype(str),
        y=y,
    )
)
fig.show(renderer="png")

Activity

  1. ayjayt commented on Dec 16, 2024

    @ayjayt
    Collaborator

    Hi! Thanks for this, I'm going to mark it active.

    I think its solved in an unreleased but already-merged pr (which may come out tomorrow or the day after).

  2. self-assigned this
    on Dec 16, 2024
  3. valankar commented on Apr 21, 2025

    @valankar

    Just came across this as well trying to switch to 1.0.0.

  4. rod7760 commented on Jun 27, 2025

    @rod7760

    I am seeing this with every format for fig.write for 1.0.0

    fig.write("figure.sv",format="svg") 
    

    So the issue title might be a bit misleading.

  5. chetanpat93 commented on Aug 5, 2025

    @chetanpat93

    Does anyone have a resultion on this?

  6. forest009839 commented on Sep 12, 2025

    @forest009839

    Smame here, I encountered this issue when exporting figures with every format in version 1.0.0
    fig.write_image("xxx")
    The exported file is not rendered correctly, although the figure displays properly within the Jupyter Notebook output.

  7. BlastoiseBlue commented on Sep 23, 2025

    @BlastoiseBlue

    It looks like the issue happens specifically when the timestamps have nanosecond resolution, which is what pandas uses by default. Changing the resolution to microseconds does seem to fix this, but it's not ideal for pandas' default behavior to cause issues like this.

  8. forest009839 commented on Sep 29, 2025

    @forest009839

    It looks like the issue happens specifically when the timestamps have nanosecond resolution, which is what pandas uses by default. Changing the resolution to microseconds does seem to fix this, but it's not ideal for pandas' default behavior to cause issues like this.

    When running the same script in the local macOS Jupyter environment, the output is normal. However, issues arise when using it on a remote Linux workstation.

  9. dsjoho commented on Oct 1, 2025

    @dsjoho

    It looks like the issue happens specifically when the timestamps have nanosecond resolution, which is what pandas uses by default. Changing the resolution to microseconds does seem to fix this, but it's not ideal for pandas' default behavior to cause issues like this.

    Thanks! This helped me solve my plotly timeline that suddenly started from 1970: df["start"] = df["start"].astype('datetime64[us]').
    Before that I tried just .dt.date, but it didn't work.

  10. z--m-n commented on Oct 16, 2025

    @z--m-n

    It looks like the issue happens specifically when the timestamps have nanosecond resolution, which is what pandas uses by default. Changing the resolution to microseconds does seem to fix this, but it's not ideal for pandas' default behavior to cause issues like this.

    Thanks! This helped me solve my plotly timeline that suddenly started from 1970: df["start"] = df["start"].astype('datetime64[us]'). Before that I tried just .dt.date, but it didn't work.

    Great! Then a start-point for an expensive workaround - until this issue is expertly fixed on the kaleido side - is by looping over columns and (multi-)index of the input data and testing for is_datetime64_ns_dtype:

    df = ... # some input DataFrame passed later to plotly express 
    
    # columns
    for n in list(df.columns):
        if pd.core.dtypes.common.is_datetime64_ns_dtype(df[n]):
            df[n] = df[n].astype("datetime64[us]")
    # index
    for n in list(df.index.names):
        if pd.core.dtypes.common.is_datetime64_ns_dtype(
            df.index.get_level_values(df.index.names.index(n))
        ):
            df.index = df.index.set_levels(
                df.index.get_level_values(df.index.names.index(n)).astype("datetime64[us]"),
                level=df.index.names.index(n),
            )

    ... probably does not go well on duplicate names. Needs improvement.

  11. BlastoiseBlue commented on Oct 16, 2025

    @BlastoiseBlue

    It looks like the issue happens specifically when the timestamps have nanosecond resolution, which is what pandas uses by default. Changing the resolution to microseconds does seem to fix this, but it's not ideal for pandas' default behavior to cause issues like this.

    Thanks! This helped me solve my plotly timeline that suddenly started from 1970: df["start"] = df["start"].astype('datetime64[us]'). Before that I tried just .dt.date, but it didn't work.

    Great! Then a start-point for an expensive workaround - until this issue is expertly fixed on the kaleido side - is by looping over columns and (multi-)index of the input data and testing for is_datetime64_ns_dtype:

    df = ... # some input DataFrame passed later to plotly express

    columns

    for n in list(df.columns):
    if pd.core.dtypes.common.is_datetime64_ns_dtype(df[n]):
    df[n] = df[n].astype("datetime64[us]")

    index

    for n in list(df.index.names):
    if pd.core.dtypes.common.is_datetime64_ns_dtype(
    df.index.get_level_values(df.index.names.index(n))
    ):
    df.index = df.index.set_levels(
    df.index.get_level_values(df.index.names.index(n)).astype("datetime64[us]"),
    level=df.index.names.index(n),
    )

    ... probably does not go well on duplicate names. Needs improvement.

    As far as re-casting the columns go, you could probably do something like dt = dt.astype({col: "datetime64[us]" for col in dt.select_dtypes("datetime64")}), or if you want to use narwhals, you could do something like df = nw.from_native(df).with_columns(ncs.by_dtype(nw.Datetime("ns")).cast(nw.Datetime("us"))).to_native().

  12. boomshankerx commented on Oct 16, 2025

    @boomshankerx

    @Honghe Nerd points for go.Figure()

  13. emilykl commented on Nov 10, 2025

    @emilykl
    Contributor

    @Honghe @ayjayt Has this specific issue been resolved? I am not able to reproduce with plotly==6.4.0 and kaleido==1.2.0.

    This code:

    import pandas as pd
    import plotly.graph_objs as go
    
    periods = 10
    x = pd.date_range("20241215T00:00:00", periods=periods, freq="h").to_numpy()
    y = list(range(periods))
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=x, y=y))
    fig.show(renderer="png")

    produces this image:
    Image

    which looks correct.

    However, there are still some similar issues with [ns] precision datetimes in Plotly.py (e.g. plotly/plotly.py#5355) which I am investigating.

  14. ayjayt commented on Nov 11, 2025

    @ayjayt
    Collaborator

    I just tested it under kaleido==1.2.0 for all png, jpg, svg, and pdf and got the same image for all- equal to yours. Closing.

    (this was likely fixed in v1.2.0!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions