GNU bug report logs -
#70687
python-matplotlib not respecting env var MPLBACKEND=TkAgg
Previous Next
Reported by: Jake <jforst.mailman <at> gmail.com>
Date: Wed, 1 May 2024 01:25:01 UTC
Severity: normal
Done: Simon Tournier <zimon.toutoune <at> gmail.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 70687 in the body.
You can then email your comments to 70687 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-guix <at> gnu.org:
bug#70687; Package
guix.
(Wed, 01 May 2024 01:25:01 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Jake <jforst.mailman <at> gmail.com>:
New bug report received and forwarded. Copy sent to
bug-guix <at> gnu.org.
(Wed, 01 May 2024 01:25:01 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hello
We are supposed to be able to control the backend used by Python's
Matplotlib via the MPLBACKEND environment variable [1]. This doesn't appear
to work for the TkAgg backend:
#+begin_src sh
guix shell python python-matplotlib -- bash -c 'MPLBACKEND=TkAgg python3
-c "import matplotlib; print(matplotlib.get_backend()); import
matplotlib.pyplot as plt; plt.plot([1],[2]); plt.show()"'
#+end_src
#+RESULTS:
: TkAgg
: <string>:1: UserWarning: FigureCanvasAgg is non-interactive, and thus
cannot be shown
However, the TkAgg backend does work if it is hardcoded in the Python
script using `matplotlib.use()`:
#+begin_src sh
guix shell python python-matplotlib -- python3 -c "import matplotlib;
matplotlib.use('TkAgg'); print(matplotlib.get_backend()); import
matplotlib.pyplot as plt; plt.plot([1],[2]); plt.show()"
#+end_src
#+RESULTS:
: TkAgg
Thanks
Jake
[1]: https://matplotlib.org/stable/users/explain/figure/backends.html
[Message part 2 (text/html, inline)]
Information forwarded
to
bug-guix <at> gnu.org:
bug#70687; Package
guix.
(Thu, 03 Apr 2025 11:38:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 70687 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
It appears that importing matplotlib.pyplot resets the Matplotlib backend
to Agg.
$ guix shell python python-matplotlib -- bash -c 'MPLBACKEND=tkagg
python3 -c "import matplotlib; print(matplotlib.get_backend()); import
matplotlib.pyplot; print(matplotlib.get_backend())"'
TkAgg
agg
On Wed, May 1, 2024 at 1:25 AM Jake <jforst.mailman <at> gmail.com> wrote:
> Hello
>
> We are supposed to be able to control the backend used by Python's
> Matplotlib via the MPLBACKEND environment variable [1]. This doesn't appear
> to work for the TkAgg backend:
>
> #+begin_src sh
>
> guix shell python python-matplotlib -- bash -c 'MPLBACKEND=TkAgg python3
> -c "import matplotlib; print(matplotlib.get_backend()); import
> matplotlib.pyplot as plt; plt.plot([1],[2]); plt.show()"'
>
> #+end_src
>
> #+RESULTS:
> : TkAgg
> : <string>:1: UserWarning: FigureCanvasAgg is non-interactive, and thus
> cannot be shown
>
> However, the TkAgg backend does work if it is hardcoded in the Python
> script using `matplotlib.use()`:
>
> #+begin_src sh
>
> guix shell python python-matplotlib -- python3 -c "import matplotlib;
> matplotlib.use('TkAgg'); print(matplotlib.get_backend()); import
> matplotlib.pyplot as plt; plt.plot([1],[2]); plt.show()"
>
> #+end_src
>
> #+RESULTS:
> : TkAgg
>
> Thanks
> Jake
>
> [1]: https://matplotlib.org/stable/users/explain/figure/backends.html
>
[Message part 2 (text/html, inline)]
Information forwarded
to
bug-guix <at> gnu.org:
bug#70687; Package
guix.
(Sat, 05 Apr 2025 23:01:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 70687 <at> debbugs.gnu.org (full text, mbox):
Hi Jake,
Am Donnerstag, dem 03.04.2025 um 11:36 +0000 schrieb Jake:
> It appears that importing matplotlib.pyplot resets the Matplotlib
> backend to Agg.
>
> $ guix shell python python-matplotlib -- bash -c 'MPLBACKEND=tkagg
> python3 -c "import matplotlib; print(matplotlib.get_backend());
> import matplotlib.pyplot; print(matplotlib.get_backend())"'
>
> TkAgg
> agg
I recently encountered the same issue. The issue is that matplotlib
internally sources a configuration file that sets the backend *after*
reading the environment variable. To circumvent this, you use
something along the lines of the following code until the issue is
fixed:
from matplotlib import set_backend
from os import environ
[…]
if __name__ == '__main__':
if 'MPLBACKEND' in environ: set_backend(environ['MPLBACKEND'])
[…]
Cheers
Information forwarded
to
bug-guix <at> gnu.org:
bug#70687; Package
guix.
(Thu, 03 Jul 2025 13:21:01 GMT)
Full text and
rfc822 format available.
Message #14 received at 70687 <at> debbugs.gnu.org (full text, mbox):
Hi Lily
It looks like this bug isn't going away anytime soon.
Here is the offending code in `lib/matplotlib/pyplot.py`, with an
added print statement:
```text
# If rcParams['backend_fallback'] is true, and an interactive backend is
# requested, ignore rcParams['backend'] and force selection of a backend that
# is compatible with the current running interactive framework.
if (rcParams["backend_fallback"]
and rcParams._get_backend_or_none() in ( # type: ignore
set(rcsetup.interactive_bk) - {'WebAgg', 'nbAgg'})
and cbook._get_running_interactive_framework()): # type: ignore
print(f"running interactive framework is:
{cbook._get_running_interactive_framework()}")
rcParams._set("backend", rcsetup._auto_backend_sentinel) # type: ignore
```
Running this
```text
MPLBACKEND=tkagg guix shell
--with-source=python-matplotlib=$HOME/matplotlib
--without-tests=python-matplotlib python python-matplotlib -- python3
-c "import matplotlib; print(matplotlib.get_backend()); import
matplotlib.pyplot as plt; print(matplotlib.get_backend())"
```
gives
```text
TkAgg
running interactive framework is: headless
agg
```
So I guess the next question is: why does it think I'm headless? To
be continued...
Thanks
Jake
On Sat, Apr 5, 2025 at 11:00 PM Liliana Marie Prikler
<liliana.prikler <at> gmail.com> wrote:
>
> Hi Jake,
>
> Am Donnerstag, dem 03.04.2025 um 11:36 +0000 schrieb Jake:
> > It appears that importing matplotlib.pyplot resets the Matplotlib
> > backend to Agg.
> >
> > $ guix shell python python-matplotlib -- bash -c 'MPLBACKEND=tkagg
> > python3 -c "import matplotlib; print(matplotlib.get_backend());
> > import matplotlib.pyplot; print(matplotlib.get_backend())"'
> >
> > TkAgg
> > agg
> I recently encountered the same issue. The issue is that matplotlib
> internally sources a configuration file that sets the backend *after*
> reading the environment variable. To circumvent this, you use
> something along the lines of the following code until the issue is
> fixed:
>
> from matplotlib import set_backend
> from os import environ
>
> […]
>
> if __name__ == '__main__':
> if 'MPLBACKEND' in environ: set_backend(environ['MPLBACKEND'])
> […]
>
> Cheers
Information forwarded
to
bug-guix <at> gnu.org:
bug#70687; Package
guix.
(Thu, 03 Jul 2025 13:49:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 70687 <at> debbugs.gnu.org (full text, mbox):
Continuing:
In `lib/matplotlib/cbook.py`, the function
`_get_running_interactive_framework` has:
```text
if not _c_internal_utils.display_is_valid():
return "headless"
```
In `src/_c_internal_utils.c` we have this docstring for `display_is_valid`:
```text
"Check whether the current X11 or Wayland display is valid.\n\n"
"On Linux, returns True if either $DISPLAY is set and XOpenDisplay(NULL)\n"
"succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)\n"
"succeeds.\n\n"
"On other platforms, always returns True."},
```
$DISPLAY is set, so it must be XOpenDisplay(NULL) failing...
I found a post [1] from a Nix user:
> For anyone else facing similar issues - I resolved this by adding the X11 library to the LD_LIBRARY_PATH of my development shell.
But I haven't made any more progress.
Cheers
Jake
[1] https://discourse.nixos.org/t/python-matplotlib-tkinter-matplotlib-reverts-to-agg-backend-because-it-cant-find-a-valid-display/45064
On Thu, Jul 3, 2025 at 1:19 PM Jake <jforst.mailman <at> gmail.com> wrote:
>
> Hi Lily
>
> It looks like this bug isn't going away anytime soon.
>
> Here is the offending code in `lib/matplotlib/pyplot.py`, with an
> added print statement:
>
> ```text
> # If rcParams['backend_fallback'] is true, and an interactive backend is
> # requested, ignore rcParams['backend'] and force selection of a backend that
> # is compatible with the current running interactive framework.
> if (rcParams["backend_fallback"]
> and rcParams._get_backend_or_none() in ( # type: ignore
> set(rcsetup.interactive_bk) - {'WebAgg', 'nbAgg'})
> and cbook._get_running_interactive_framework()): # type: ignore
> print(f"running interactive framework is:
> {cbook._get_running_interactive_framework()}")
> rcParams._set("backend", rcsetup._auto_backend_sentinel) # type: ignore
> ```
>
> Running this
>
> ```text
> MPLBACKEND=tkagg guix shell
> --with-source=python-matplotlib=$HOME/matplotlib
> --without-tests=python-matplotlib python python-matplotlib -- python3
> -c "import matplotlib; print(matplotlib.get_backend()); import
> matplotlib.pyplot as plt; print(matplotlib.get_backend())"
> ```
>
> gives
>
> ```text
> TkAgg
> running interactive framework is: headless
> agg
> ```
>
> So I guess the next question is: why does it think I'm headless? To
> be continued...
>
> Thanks
> Jake
>
>
> On Sat, Apr 5, 2025 at 11:00 PM Liliana Marie Prikler
> <liliana.prikler <at> gmail.com> wrote:
> >
> > Hi Jake,
> >
> > Am Donnerstag, dem 03.04.2025 um 11:36 +0000 schrieb Jake:
> > > It appears that importing matplotlib.pyplot resets the Matplotlib
> > > backend to Agg.
> > >
> > > $ guix shell python python-matplotlib -- bash -c 'MPLBACKEND=tkagg
> > > python3 -c "import matplotlib; print(matplotlib.get_backend());
> > > import matplotlib.pyplot; print(matplotlib.get_backend())"'
> > >
> > > TkAgg
> > > agg
> > I recently encountered the same issue. The issue is that matplotlib
> > internally sources a configuration file that sets the backend *after*
> > reading the environment variable. To circumvent this, you use
> > something along the lines of the following code until the issue is
> > fixed:
> >
> > from matplotlib import set_backend
> > from os import environ
> >
> > […]
> >
> > if __name__ == '__main__':
> > if 'MPLBACKEND' in environ: set_backend(environ['MPLBACKEND'])
> > […]
> >
> > Cheers
Information forwarded
to
bug-guix <at> gnu.org:
bug#70687; Package
guix.
(Fri, 04 Jul 2025 08:10:03 GMT)
Full text and
rfc822 format available.
Message #20 received at 70687 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Fixed, I think. We just need to patch a dlopen call.
Now TkAgg works out of the box, without requiring changes to user Python
code. I hope that also means we can change the default backend from Agg to
TkAgg.
Submitted this PR (and got lucky number 1000!)
https://codeberg.org/guix/guix/pulls/1000
with the fix and change of backend.
Cheers
Jake
On Thu, 3 Jul 2025 at 11:18 pm, Jake <jforst.mailman <at> gmail.com> wrote:
> Continuing:
> In `lib/matplotlib/cbook.py`, the function
> `_get_running_interactive_framework` has:
>
> ```text
> if not _c_internal_utils.display_is_valid():
> return "headless"
> ```
>
> In `src/_c_internal_utils.c` we have this docstring for `display_is_valid`:
>
> ```text
> "Check whether the current X11 or Wayland display is valid.\n\n"
> "On Linux, returns True if either $DISPLAY is set and
> XOpenDisplay(NULL)\n"
> "succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)\n"
> "succeeds.\n\n"
> "On other platforms, always returns True."},
> ```
>
> $DISPLAY is set, so it must be XOpenDisplay(NULL) failing...
>
> I found a post [1] from a Nix user:
> > For anyone else facing similar issues - I resolved this by adding the
> X11 library to the LD_LIBRARY_PATH of my development shell.
>
> But I haven't made any more progress.
>
> Cheers
> Jake
>
> [1]
> https://discourse.nixos.org/t/python-matplotlib-tkinter-matplotlib-reverts-to-agg-backend-because-it-cant-find-a-valid-display/45064
>
> On Thu, Jul 3, 2025 at 1:19 PM Jake <jforst.mailman <at> gmail.com> wrote:
> >
> > Hi Lily
> >
> > It looks like this bug isn't going away anytime soon.
> >
> > Here is the offending code in `lib/matplotlib/pyplot.py`, with an
> > added print statement:
> >
> > ```text
> > # If rcParams['backend_fallback'] is true, and an interactive backend is
> > # requested, ignore rcParams['backend'] and force selection of a backend
> that
> > # is compatible with the current running interactive framework.
> > if (rcParams["backend_fallback"]
> > and rcParams._get_backend_or_none() in ( # type: ignore
> > set(rcsetup.interactive_bk) - {'WebAgg', 'nbAgg'})
> > and cbook._get_running_interactive_framework()): # type: ignore
> > print(f"running interactive framework is:
> > {cbook._get_running_interactive_framework()}")
> > rcParams._set("backend", rcsetup._auto_backend_sentinel) # type:
> ignore
> > ```
> >
> > Running this
> >
> > ```text
> > MPLBACKEND=tkagg guix shell
> > --with-source=python-matplotlib=$HOME/matplotlib
> > --without-tests=python-matplotlib python python-matplotlib -- python3
> > -c "import matplotlib; print(matplotlib.get_backend()); import
> > matplotlib.pyplot as plt; print(matplotlib.get_backend())"
> > ```
> >
> > gives
> >
> > ```text
> > TkAgg
> > running interactive framework is: headless
> > agg
> > ```
> >
> > So I guess the next question is: why does it think I'm headless? To
> > be continued...
> >
> > Thanks
> > Jake
> >
> >
> > On Sat, Apr 5, 2025 at 11:00 PM Liliana Marie Prikler
> > <liliana.prikler <at> gmail.com> wrote:
> > >
> > > Hi Jake,
> > >
> > > Am Donnerstag, dem 03.04.2025 um 11:36 +0000 schrieb Jake:
> > > > It appears that importing matplotlib.pyplot resets the Matplotlib
> > > > backend to Agg.
> > > >
> > > > $ guix shell python python-matplotlib -- bash -c 'MPLBACKEND=tkagg
> > > > python3 -c "import matplotlib; print(matplotlib.get_backend());
> > > > import matplotlib.pyplot; print(matplotlib.get_backend())"'
> > > >
> > > > TkAgg
> > > > agg
> > > I recently encountered the same issue. The issue is that matplotlib
> > > internally sources a configuration file that sets the backend *after*
> > > reading the environment variable. To circumvent this, you use
> > > something along the lines of the following code until the issue is
> > > fixed:
> > >
> > > from matplotlib import set_backend
> > > from os import environ
> > >
> > > […]
> > >
> > > if __name__ == '__main__':
> > > if 'MPLBACKEND' in environ: set_backend(environ['MPLBACKEND'])
> > > […]
> > >
> > > Cheers
>
[Message part 2 (text/html, inline)]
Reply sent
to
Simon Tournier <zimon.toutoune <at> gmail.com>:
You have taken responsibility.
(Wed, 20 Aug 2025 18:05:03 GMT)
Full text and
rfc822 format available.
Notification sent
to
Jake <jforst.mailman <at> gmail.com>:
bug acknowledged by developer.
(Wed, 20 Aug 2025 18:05:04 GMT)
Full text and
rfc822 format available.
Message #25 received at 70687-done <at> debbugs.gnu.org (full text, mbox):
Hi,
On Fri, 04 Jul 2025 at 17:39, Jake <jforst.mailman <at> gmail.com> wrote:
> Fixed, I think. We just need to patch a dlopen call.
>
> Now TkAgg works out of the box, without requiring changes to user Python
> code. I hope that also means we can change the default backend from Agg to
> TkAgg.
>
> Submitted this PR (and got lucky number 1000!)
> https://codeberg.org/guix/guix/pulls/1000
> with the fix and change of backend.
As far as I see, guix/guix#1000 had been merged, so I’m closing this
issue.
If I’m missing something, feel free to reopen. :-)
Cheers,
simon
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org.
(Thu, 18 Sep 2025 11:24:11 GMT)
Full text and
rfc822 format available.
This bug report was last modified 60 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.