Skip to content

save_image not working in python-kaleido v1 #2475

Closed

Description

@ZacharyHu0
> library(plotly)
+ fig <- plot_ly(z = ~volcano) %>% add_surface()
+ save_image(fig, "surface-plot.svg")
Error in `py_get_attr()`:
! AttributeError: module 'kaleido' has no attribute 'scopes'
Run `reticulate::py_last_error()` for details.
Hide Traceback
    ▆
 1. └─plotly::save_image(fig, "surface-plot.svg")
 2.   └─plotly::kaleido()
 3.     ├─kaleido$scopes
 4.     └─reticulate:::`$.python.builtin.module`(kaleido, "scopes")
 5.       └─reticulate::py_get_attr(x, name, FALSE)

I'm running the latest master branch version 4868a68f installed by:
remotes::install_github("plotly/plotly")

R=4.4.3
Python=3.12.12

I've noticed the merge
Add support for kaleido v1.0 (save_image()); fix CI #2447

It seems the merge #2447 didn't work as expected, since "kaleido.scopes.plotly has been removed in v1."

Activity

  1. changed the title [-]save_image not working in[/-] [+]save_image not working in python-kaleido v1[/+] on Jan 23, 2026
  2. ZacharyHu0 commented on Jan 23, 2026

    @ZacharyHu0
    Author

    here's my Conda list:

    # packages in environment at /Volumes/Data/miniconda3/envs/r-reticulate:
    #
    # Name                     Version          Build                Channel
    _openmp_mutex              4.5              7_kmp_llvm           conda-forge
    bzip2                      1.0.8            hd037594_8           conda-forge
    ca-certificates            2026.1.4         hbd8a1cb_0           conda-forge
    choreographer              1.2.1            pyhcf101f3_0         conda-forge
    colorama                   0.4.6            pyhd8ed1ab_1         conda-forge
    exceptiongroup             1.3.1            pyhd8ed1ab_0         conda-forge
    icu                        78.2             h38cb7af_0           conda-forge
    iniconfig                  2.3.0            pyhd8ed1ab_0         conda-forge
    libblas                    3.11.0           5_h51639a9_openblas  conda-forge
    libcblas                   3.11.0           5_hb0561ab_openblas  conda-forge
    libcxx                     21.1.8           hf598326_0           conda-forge
    libexpat                   2.7.3            haf25636_0           conda-forge
    libffi                     3.5.2            he5f378a_0           conda-forge
    libgcc                     15.2.0           hcbb3090_16          conda-forge
    libgfortran                15.2.0           h07b0088_16          conda-forge
    libgfortran5               15.2.0           hdae7583_16          conda-forge
    liblapack                  3.11.0           5_hd9741b5_openblas  conda-forge
    liblzma                    5.8.2            h8088a28_0           conda-forge
    libopenblas                0.3.30           openmp_ha158390_4    conda-forge
    libsqlite                  3.51.2           h1ae2325_0           conda-forge
    libzlib                    1.3.1            h8359307_2           conda-forge
    llvm-openmp                21.1.8           h4a912ad_0           conda-forge
    logistro                   2.0.1            pyhcf101f3_0         conda-forge
    narwhals                   2.15.0           pyhcf101f3_0         conda-forge
    ncurses                    6.5              h5e97a16_3           conda-forge
    numpy                      2.4.1            py312he281c53_0      conda-forge
    openssl                    3.6.0            h5503f6c_0           conda-forge
    orjson                     3.11.5           py312h6f167cc_0      conda-forge
    packaging                  26.0             pyhcf101f3_0         conda-forge
    pip                        25.3             pyh8b19718_0         conda-forge
    plotly                     6.0.0            py_0                 plotly
    pluggy                     1.6.0            pyhf9edf01_1         conda-forge
    pygments                   2.19.2           pyhd8ed1ab_0         conda-forge
    pytest                     9.0.2            pyhcf101f3_0         conda-forge
    pytest-timeout             2.4.0            pyhd8ed1ab_0         conda-forge
    python                     3.12.12          h18782d2_1_cpython   conda-forge
    python-kaleido             1.2.0            pyhcf101f3_0         conda-forge
    python_abi                 3.12             8_cp312              conda-forge
    readline                   8.3              h46df422_0           conda-forge
    setuptools                 80.10.1          pyh332efcf_0         conda-forge
    simplejson                 3.20.2           py312h4409184_1      conda-forge
    tk                         8.6.13           h892fb3f_3           conda-forge
    tomli                      2.4.0            pyhcf101f3_0         conda-forge
    typing_extensions          4.15.0           pyhcf101f3_0         conda-forge
    tzdata                     2025c            hc9c84f9_1           conda-forge
    wheel                      0.46.3           pyhd8ed1ab_0         conda-forge
    
  3. cpsievert commented on Jan 23, 2026

    @cpsievert
    Collaborator

    Thanks for reporting this! I've pushed a fix in commit b1103b2.

    The issue was that the code was using tryNULL(kaleido$scopes) to detect whether kaleido v1 was installed, but accessing a non-existent Python attribute can throw an AttributeError that doesn't always get caught properly by R's tryCatch. The fix uses reticulate::py_has_attr() instead, which safely checks for attribute existence without triggering the error.

    Would you mind reinstalling from GitHub and letting me know if this resolves the issue for you?

    remotes::install_github("plotly/plotly.R")

    Thanks again for the detailed report!

  4. dschulz13 commented on Jan 25, 2026

    @dschulz13

    I had the same issue as @ZacharyHu0. The fix solves this error; however, on my Windows laptop I do now instead get the error

    Error in py_run_string_impl(code, local, convert) : 
        File "<string>", line 1
        import json; fig = json.load(open('C:\Users\DOMINI~1\AppData\Local\Temp\Rtmpa49Ihy\file26a4639245df.json'))
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
    

    when running save_image(). It seems to me like the temporary file path is not adjusted properly to use / instead of \ when being passed to py_run_string() within newKaleidoScope().

    Edit:
    As a suggestion, the line 138 in the file kaleido.R should read normalizePath(tmp_json, winslash = "/").

  5. cpsievert commented on Jan 26, 2026

    @cpsievert
    Collaborator

    Thanks for reporting. Would you like to contribute a PR and verify the fix?

  6. dschulz13 commented on Jan 27, 2026

    @dschulz13

    I would love to, but unfortunately I do not have the time currently.

  7. ZacharyHu0 commented on Jan 30, 2026

    @ZacharyHu0
    Author

    Would you mind reinstalling from GitHub and letting me know if this resolves the issue for you?

    remotes::install_github("plotly/plotly.R")

    I can confirm the fix works smoothly.
    Thank you for your contribution to this community !

    my Conda environment for reference:

    r-plotly           4.12.0.9000           [f7acae4]
    kaleido           1.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