"bad screen distance" tkinter error with German locale

Hi,

sorry if this has already been addressed. I did a search on the archives, but even though that turned up lots of hits, none of them seemed to be related to the issue.

The following very simple example will reliably crash in Python 2.7.[0-2] with matplotlib 1.0.1 under a 64 bit German Windows (and probably also on other machines where you can set an equivalent locale):

···

---

import matplotlib

from pylab import arange,sin,pi
t = arange(0.0, 2.0, 0.01)
s = sin(2*pi*t)

import locale
# the locale setting in the next line makes pyplot.plot crash
# have to use "deu_deu" instead of "de_DE" on German Windows
locale.setlocale(locale.LC_ALL, 'deu_deu')
print "locale =", locale.getlocale(locale.LC_NUMERIC)

print "will plot ..."
matplotlib.pyplot.plot(t, s, linewidth=1.0)
# doesn't get this far with German locale
print "will show ..."
matplotlib.pyplot.show()

---

The program crashes in pyplot.plot(). The stacktrace is:

---

Traceback (most recent call last):
  File "C:\[...]\badScreenSizeMPL.py", line 14, in <module>
    matplotlib.pyplot.plot(t, s, linewidth=1.0)
  File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 2279, in plot
    ax = gca()
  File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 593, in gca
    ax = gcf().gca(**kwargs)
  File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 292, in gcf
    return figure()
  File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 270, in figure
    **kwargs)
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 82, in new_figure_manager
    figManager = FigureManagerTkAgg(canvas, num, window)
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 400, in __init__
    self.toolbar = NavigationToolbar2TkAgg( canvas, self.window )
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 667, in __init__
    NavigationToolbar2.__init__(self, canvas)
  File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 2310, in __init__
    self._init_toolbar()
  File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 711, in _init_toolbar
    borderwidth=2)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 2466, in __init__
    Widget.__init__(self, master, 'frame', cnf, {}, extra)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1977, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: bad screen distance "640.0"
Fatal Python error: PyEval_RestoreThread: NULL tstate

---

The reason appears to be that at some point Tkinter tries to parse the string "640.0" as a number, which does not work in a locale where the decimal marker is, e.g., the comma (as in German). If you comment out the locale setting (or set it to "C"), the example works.

The float value of 640.0 seems to emerge from the following piece of code in "backend_tkagg.py".

---

class NavigationToolbar2TkAgg(NavigationToolbar2, Tk.Frame):

   [...]

    def _init_toolbar(self):
        xmin, xmax = self.canvas.figure.bbox.intervalx
        height, width = 50, xmax-xmin
        Tk.Frame.__init__(self, master=self.window,
                          width=width, height=height,
                          borderwidth=2)

---

Through the initialization by difference, "width" is a 'numpy.float64'; changing the assignment of "height, width" to

   height, width = 50, int(xmax-xmin)

makes the example program run through without problems.

One the one hand, I guess this should be fixed in the depths of Tkinter (where apparently a number type gets stringified just to be parsed again as a number). One the other hand, it would be very simple fix in the TkAgg backend, and it seems sensible to make the width an int. (Perhaps even the intervals in intervalx should already be ints?)

I would like to point out that, even though this might sound like a contrived problem, it can easily occur where machines are set up with different languages; we had a tool run on an English Windows, but we got the stack trace from above when we moved that tool to a German Windows which we believed to be set up in just the same way as the original Windows. It took us a day to figure out what the reason behind the cryptic Tkinter error was.

Kind regards,
H.

Thanks for the report. Indeed this is a problem. I've filed a pull request with a fix here:

https://github.com/matplotlib/matplotlib/pull/387

There were a few other places where we weren't absolutely ensuring the passing of ints to Tkinter that I also fixed.

I'm surprised this bug (which really lies in Tkinter) isn't more widely known -- searching the Python bug tracker revealed nothing. It would be great to follow-up there (with a standalone Tkinter-crashing example) if you're so inclined.

Cheers,
Mike

···

On 06/30/2011 11:48 AM, hans.bering@...2007... wrote:

Hi,

sorry if this has already been addressed. I did a search on the archives, but even though that turned up lots of hits, none of them seemed to be related to the issue.

The following very simple example will reliably crash in Python 2.7.[0-2] with matplotlib 1.0.1 under a 64 bit German Windows (and probably also on other machines where you can set an equivalent locale):

---

import matplotlib

from pylab import arange,sin,pi
t = arange(0.0, 2.0, 0.01)
s = sin(2*pi*t)

import locale
# the locale setting in the next line makes pyplot.plot crash
# have to use "deu_deu" instead of "de_DE" on German Windows
locale.setlocale(locale.LC_ALL, 'deu_deu')
print "locale =", locale.getlocale(locale.LC_NUMERIC)

print "will plot ..."
matplotlib.pyplot.plot(t, s, linewidth=1.0)
# doesn't get this far with German locale
print "will show ..."
matplotlib.pyplot.show()

---

The program crashes in pyplot.plot(). The stacktrace is:

---

Traceback (most recent call last):
   File "C:\[...]\badScreenSizeMPL.py", line 14, in<module>
     matplotlib.pyplot.plot(t, s, linewidth=1.0)
   File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 2279, in plot
     ax = gca()
   File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 593, in gca
     ax = gcf().gca(**kwargs)
   File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 292, in gcf
     return figure()
   File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 270, in figure
     **kwargs)
   File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 82, in new_figure_manager
     figManager = FigureManagerTkAgg(canvas, num, window)
   File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 400, in __init__
     self.toolbar = NavigationToolbar2TkAgg( canvas, self.window )
   File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 667, in __init__
     NavigationToolbar2.__init__(self, canvas)
   File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 2310, in __init__
     self._init_toolbar()
   File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 711, in _init_toolbar
     borderwidth=2)
   File "C:\Python27\lib\lib-tk\Tkinter.py", line 2466, in __init__
     Widget.__init__(self, master, 'frame', cnf, {}, extra)
   File "C:\Python27\lib\lib-tk\Tkinter.py", line 1977, in __init__
     (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: bad screen distance "640.0"
Fatal Python error: PyEval_RestoreThread: NULL tstate

---

The reason appears to be that at some point Tkinter tries to parse the string "640.0" as a number, which does not work in a locale where the decimal marker is, e.g., the comma (as in German). If you comment out the locale setting (or set it to "C"), the example works.

The float value of 640.0 seems to emerge from the following piece of code in "backend_tkagg.py".

---

class NavigationToolbar2TkAgg(NavigationToolbar2, Tk.Frame):

    [...]

     def _init_toolbar(self):
         xmin, xmax = self.canvas.figure.bbox.intervalx
         height, width = 50, xmax-xmin
         Tk.Frame.__init__(self, master=self.window,
                           width=width, height=height,
                           borderwidth=2)

---

Through the initialization by difference, "width" is a 'numpy.float64'; changing the assignment of "height, width" to

    height, width = 50, int(xmax-xmin)

makes the example program run through without problems.

One the one hand, I guess this should be fixed in the depths of Tkinter (where apparently a number type gets stringified just to be parsed again as a number). One the other hand, it would be very simple fix in the TkAgg backend, and it seems sensible to make the width an int. (Perhaps even the intervals in intervalx should already be ints?)

I would like to point out that, even though this might sound like a contrived problem, it can easily occur where machines are set up with different languages; we had a tool run on an English Windows, but we got the stack trace from above when we moved that tool to a German Windows which we believed to be set up in just the same way as the original Windows. It took us a day to figure out what the reason behind the cryptic Tkinter error was.

Kind regards,
H.

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

--
Michael Droettboom
Science Software Branch
Space Telescope Science Institute
Baltimore, Maryland, USA

I did find this bug, which seems to be related.

Mike

···

On 06/30/2011 01:10 PM, Michael Droettboom wrote:

I'm surprised this bug (which really lies in Tkinter) isn't more widely
known -- searching the Python bug tracker revealed nothing. It would be
great to follow-up there (with a standalone Tkinter-crashing example) if
you're so inclined.

--
Michael Droettboom
Science Software Branch
Space Telescope Science Institute
Baltimore, Maryland, USA

I did find this bug, which seems to be related.

http://bugs.python.org/issue10647

Mike

···

On 06/30/2011 01:10 PM, Michael Droettboom wrote:

I'm surprised this bug (which really lies in Tkinter) isn't more widely
known -- searching the Python bug tracker revealed nothing. It would be
great to follow-up there (with a standalone Tkinter-crashing example) if
you're so inclined.

--
Michael Droettboom
Science Software Branch
Space Telescope Science Institute
Baltimore, Maryland, USA