Simultaneous plots with Matplotlib "QObject/thread" error

Hi all,

I have some Flask pages that plot charts using Matplotlib, they work
very well, but when running them simultaneously they break the site,
with errors like:

"QObject: Cannot create children for a parent that is in a different
thread."

"QObject::~QObject: Timers cannot be stopped from another thread"

I wonder how to safely use Matplolib with Flask (with several
simultaneous users plotting charts all the time)?

Thank you,
John

Hi all,

I have some Flask pages that plot charts using Matplotlib, they work
very well, but when running them simultaneously they break the site,
with errors like:

"QObject: Cannot create children for a parent that is in a different
thread."

"QObject::~QObject: Timers cannot be stopped from another thread"

I wonder how to safely use Matplolib with Flask (with several
simultaneous users plotting charts all the time)?

I suspect the problem is that matplotlib is running with the qt4agg backend.

When plotting for a web app like that, you need to make sure the backend
is set to the agg backend. You can do that in a matplotlibrc file or
directly in the plotting script, immediately after importing matplotlib
and before importing pyplot (if you use pyplot at all).

Eric

···

On 2016/09/08 8:40 PM, John Robson wrote:

Thank you,
John

Eric, you are right, I followed this and worked:

http://matplotlib.org/faq/howto_faq.html#howto-webapp

I also fixed other problems, I was using "plt.savefig", "plt.xxx" I
believe that this "plt" was harming other simultaneous plots, so I
replaced every "plt." by ".fig" and now I think is OK.

I just wonder how can I isolate each plot from other simultaneous plots,
I'm doing this:

fig = plt.figure()
ax = fig.gca()
> plot stuff, scatterplot, etc..., set title, lables, etc...
fig = ax.get_figure()
fig.set_tight_layout(True)
fig.savefig(filename, format='png', dpi=100, facecolor='w',
edgecolor='k', bbox_inches='tight')
fig.clf()
plt.close(fig)

So the first "fig" instance is destroyed at the end and there is no
"plt.xxx"

This is a good approach to isolate all plots?

Thank you,
John

···

On 09/09/16 03:16, Eric Firing wrote:

On 2016/09/08 8:40 PM, John Robson wrote:

Hi all,

I have some Flask pages that plot charts using Matplotlib, they work
very well, but when running them simultaneously they break the site,
with errors like:

"QObject: Cannot create children for a parent that is in a different
thread."

"QObject::~QObject: Timers cannot be stopped from another thread"

I wonder how to safely use Matplolib with Flask (with several
simultaneous users plotting charts all the time)?

I suspect the problem is that matplotlib is running with the qt4agg
backend.

When plotting for a web app like that, you need to make sure the backend
is set to the agg backend. You can do that in a matplotlibrc file or
directly in the plotting script, immediately after importing matplotlib
and before importing pyplot (if you use pyplot at all).

Eric

Thank you,
John

John,

Your new approach looks good to me, but could be tweaked. You don't
need the 'fig.clf()' at the end because the 'plt.close(fig)' will take
care of cleaning everything up. At the start, using 'fig.gca()' seems a
little odd. A common and compact idiom now would be 'fig, ax =
plt.subplots()'. Once you have the figure reference, you don't need to
recreate it with the call to 'ax.get_figure()`, so you can delete that.
I don't think you need both tight_layout and bbox_inches='tight'. My
impression is that the latter is more robust, but has the possible
disadvantage of modifying the figure dimensions, which might be
undesirable in a web app.

Eric

···

On 2016/09/09 11:24 AM, John Robson wrote:

Eric, you are right, I followed this and worked:

http://matplotlib.org/faq/howto_faq.html#howto-webapp

I also fixed other problems, I was using "plt.savefig", "plt.xxx" I
believe that this "plt" was harming other simultaneous plots, so I
replaced every "plt." by ".fig" and now I think is OK.

I just wonder how can I isolate each plot from other simultaneous plots,
I'm doing this:

fig = plt.figure()
ax = fig.gca()

plot stuff, scatterplot, etc..., set title, lables, etc...

fig = ax.get_figure()
fig.set_tight_layout(True)
fig.savefig(filename, format='png', dpi=100, facecolor='w',
edgecolor='k', bbox_inches='tight')
fig.clf()
plt.close(fig)

So the first "fig" instance is destroyed at the end and there is no
"plt.xxx"

This is a good approach to isolate all plots?

Thank you,
John

On 09/09/16 03:16, Eric Firing wrote:

On 2016/09/08 8:40 PM, John Robson wrote:

Hi all,

I have some Flask pages that plot charts using Matplotlib, they work
very well, but when running them simultaneously they break the site,
with errors like:

"QObject: Cannot create children for a parent that is in a different
thread."

"QObject::~QObject: Timers cannot be stopped from another thread"

I wonder how to safely use Matplolib with Flask (with several
simultaneous users plotting charts all the time)?

I suspect the problem is that matplotlib is running with the qt4agg
backend.

When plotting for a web app like that, you need to make sure the backend
is set to the agg backend. You can do that in a matplotlibrc file or
directly in the plotting script, immediately after importing matplotlib
and before importing pyplot (if you use pyplot at all).

Eric

Thank you,
John

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

I implemented what you suggested; I hope do not have problems with lack
of isolation when plot several figures at the same time, thank you.

Btw, for a better management of several simultaneous plots, what do you
recommend: a task queue like Celery? something else?

Tks
John

John,

I don't have a clear picture of your situation, and I've never heard of
Celery before. Maybe someone else on this list will be better qualified
to answer.

Eric

···

On 2016/09/09 2:31 PM, John Robson wrote:

Btw, for a better management of several simultaneous plots, what do you
recommend: a task queue like Celery? something else?