Export file using ovito.io.export_file

I am using python-ovito 3.9.3 pypi version on the Windows 10 operating system.
Below is a simplified version of my code. I am using ovito.io.import_file to import a file, plotting with matplotlib in the middle, and then exporting the file using ovito.io.export_file.

When running the program, I encountered the following error after closing the plot window:

exporter.do_export()
RuntimeError: No scene has been specified for file export.

After removing plt.show(), the program is able to export the file successfully.

Is this behavior normal?

Thank you in advance.

Code and data provided:

import os
os.environ['OVITO_GUI_MODE'] = '1'
import numpy as np
import ovito
import matplotlib.pyplot as plt


def main():
    dump_file = "./dump.colloid"

    pipeline_atoms = ovito.io.import_file(dump_file).compute(0)

    plt.plot(np.random.random((4, 2)))
    plt.show()

    ovito.io.export_file(pipeline_atoms, "tst.colloid", "lammps/dump", columns=["Particle Identifier", "Particle Type", "Position.X", "Position.Y", "Position.Z", "dwf"])


main()

dump.colloid (359 Bytes)

I was able to reproduce the problem (under macOS), but it took an in-depth analysis of the Matplotlib source code to understand the cause.

It is an unfortunate interaction between the Qt backend of Matplotlib and the OVITO module. Both use the same Qt cross-platform framework internally. OVITO requires a working Qt application object with a running event loop for its data processing, file I/O and rendering functions. However, the plt.show() function is misbehaving and shuts down the global Qt application object completely after the plot window has been closed by the user. OVITO can then no longer operate normally. Restarting the Qt application object does not appear to be possible due to restrictions within the Qt framework itself, which is also shown by the fact that plt.show() won’t work when called a second time.

I have found a workaround with some effort. Instead of plt.show() you can do the following:

import matplotlib as mpl

fig = plt.gcf()
mpl._blocking_input.blocking_input_loop(fig, ['close_event'], 0, lambda evt: fig.canvas.stop_event_loop())

Then another local event loop is started, and Matplotlib won’t shut down the whole Qt application. However, this is not a proper solution. We will think about whether something can be changed on the OVITO side in the future to make the Python module less dependent on the Qt application object. This will require major changes to the code though.

Thank you for your reply.