plotly / Kaleido

Fast static image export for web-based visualization libraries with zero dependencies
MIT License
378 stars 38 forks source link

Errors when rendering pdf #180

Open baraldian opened 7 months ago

baraldian commented 7 months ago

Hello I'm having an issue in saving pdf from plotly images. I can save them as html, svg, but not in pdf. When I run

import os
import plotly.express as px
fig = px.scatter(px.data.iris(), x="sepal_length", y="sepal_width", color="species")
tmp = os.path.join(os.getcwd(), 'tmp')
fig.write_image(os.path.join(tmp, '00.pdf'), engine="kaleido")

I get the error:

ValueError: Failed to start Kaleido subprocess. Error stream:

[0423/145217.606018:WARNING:resource_bundle.cc(431)] locale_file_path.empty() for locale 
[0423/145217.617618:WARNING:resource_bundle.cc(431)] locale_file_path.empty() for locale 
[0423/145217.617827:WARNING:resource_bundle.cc(431)] locale_file_path.empty() for locale 
[0423/145217.618663:WARNING:discardable_shared_memory_manager.cc(194)] Less than 64MB of free space in temporary directory for shared memory files: 0
Received signal 6
#0 0x5582aa9dcd79 base::debug::CollectStackTrace()
#1 0x5582aa95a633 base::debug::StackTrace::StackTrace()
#2 0x5582aa9dc95b base::debug::(anonymous namespace)::StackDumpSignalHandler()
#3 0x7f249c8183c0 (/usr/lib/x86_64-linux-gnu/libpthread-2.31.so+0x153bf)
#4 0x7f249bb0418b gsignal
#5 0x7f249bae3859 abort
#6 0x5582aa98830a base::internal::OnNoMemoryInternal()
#7 0x5582aa988329 base::(anonymous namespace)::OnNoMemory()
#8 0x5582aa988319 base::TerminateBecauseOutOfMemory()
#9 0x5582aa9720ab base::FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded()
#10 0x5582aa972239 base::FieldTrialList::CopyFieldTrialStateToFlags()
#11 0x5582a94cdf82 content::GpuProcessHost::LaunchGpuProcess()
#12 0x5582a94cc910 content::GpuProcessHost::Init()
#13 0x5582a94cc6c2 content::GpuProcessHost::Get()
#14 0x5582a98e9b6e base::internal::Invoker<>::RunOnce()
#15 0x5582aa9a0306 base::TaskAnnotator::RunTask()
#16 0x5582aa9b1cf6 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl()
#17 0x5582aa9b19ea base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork()
#18 0x5582aa9fe899 base::MessagePumpLibevent::Run()
#19 0x5582aa9b259b base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run()
#20 0x5582aa98b9bd base::RunLoop::Run()
#21 0x5582a9373f18 content::BrowserProcessSubThread::IOThreadRun()
#22 0x5582aa9ca874 base::Thread::ThreadMain()
#23 0x5582aa9eccaa base::(anonymous namespace)::ThreadFunc()
#24 0x7f249c80c609 start_thread
#25 0x7f249bbe0293 clone
  r8: 0000000000000000  r9: 00007f249913af50 r10: 0000000000000008 r11: 0000000000000246
 r12: 00005582a73be780 r13: 00005582a7300eb0 r14: 000019c99781ccc0 r15: 000019c99799d080
  di: 0000000000000002  si: 00007f249913af50  bp: 00007f249913b1b0  bx: 00007f249913c700
  dx: 0000000000000000  ax: 0000000000000000  cx: 00007f249bb0418b  sp: 00007f249913af50
  ip: 00007f249bb0418b efl: 0000000000000246 cgf: 002b000000000033 erf: 0000000000000000
 trp: 0000000000000000 msk: 0000000000000000 cr2: 0000000000000000
[end of stack trace]
Calling _exit(1). Core file will not be generated.

I tried a workaround with

import os
import plotly.express as px
import plotly.io as pio

pio.kaleido.scope.chromium_args = tuple([
    arg for arg in pio.kaleido.scope.chromium_args if arg != "--disable-dev-shm-usage"
])
fig = px.scatter(px.data.iris(), x="sepal_length", y="sepal_width", color="species")
# tmp folder
tmp = os.path.join(os.getcwd(), 'tmp')
fig.write_image(os.path.join(tmp, '00.pdf'), engine="kaleido")

and still gives an error:

ValueError                                Traceback (most recent call last)
Input In [2], in <cell line: 11>()
      9 # tmp folder
     10 tmp = os.path.join(os.getcwd(), 'tmp')
---> 11 fig.write_image(os.path.join(tmp, '00.pdf'), engine="kaleido")

File ...lib/python3.10/site-packages/plotly/basedatatypes.py:3841, in BaseFigure.write_image(self, *args, **kwargs)
   3781 """
   3782 Convert a figure to a static image and write it to a file or writeable
   3783 object
   (...)
   3837 None
   3838 """
   3839 import plotly.io as pio
-> 3841 return pio.write_image(self, *args, **kwargs)

File ...lib/python3.10/site-packages/plotly/io/_kaleido.py:266, in write_image(fig, file, format, scale, width, height, validate, engine)
    250             raise ValueError(
    251                 """
    252 Cannot infer image type from output path '{file}'.
   (...)
    260                 )
    261             )
    263     # Request image
    264     # -------------
    265     # Do this first so we don't create a file if image conversion fails
--> 266     img_data = to_image(
    267         fig,
    268         format=format,
    269         scale=scale,
    270         width=width,
    271         height=height,
    272         validate=validate,
    273         engine=engine,
    274     )
    276     # Open file
    277     # ---------
    278     if path is None:
    279         # We previously failed to make sense of `file` as a pathlib object.
    280         # Attempt to write to `file` as an open file descriptor.

File ...lib/python3.10/site-packages/plotly/io/_kaleido.py:143, in to_image(fig, format, width, height, scale, validate, engine)
    140 # Validate figure
    141 # ---------------
    142 fig_dict = validate_coerce_fig_to_dict(fig, validate)
--> 143 img_bytes = scope.transform(
    144     fig_dict, format=format, width=width, height=height, scale=scale
    145 )
    147 return img_bytes

File ...lib/python3.10/site-packages/kaleido/scopes/plotly.py:161, in PlotlyScope.transform(self, figure, format, width, height, scale)
    159 if code != 0:
    160     message = response.get("message", None)
--> 161     raise ValueError(
    162         "Transform failed with error code {code}: {message}".format(
    163             code=code, message=message
    164         )
    165     )
    167 img = response.get("result").encode("utf-8")
    169 # Base64 decode binary types

ValueError: Transform failed with error code 525: Cannot set property 'innerHTML' of null

I'm using a machine with Linux 5.4.0-73-generic #82-Ubuntu SMP Wed Apr 14 17:39:42 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux I installed conda with conda install -c conda-forge python-kaleido And I have installed

plotly                    5.21.0                   pypi_0    pypi
kaleido-core              0.2.1                h3644ca4_0    conda-forge
python-kaleido            0.2.1              pyhd8ed1ab_0    conda-forge

Thank you.

gvwilson commented 3 months ago

Thanks for your interest in Kaleido. We are currently working on an overhaul that might address your issue - we hope to have news in a few weeks and will post an update then. Thanks - @gvwilson