GNU bug report logs -
#70687
python-matplotlib not respecting env var MPLBACKEND=TkAgg
Previous Next
To reply to this bug, email your comments to 70687 AT debbugs.gnu.org.
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)]
This bug report was last modified 9 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.