------------------------ MDE: the Matplotlib Desktop
> Environment
Thanks for the hard work there Dr Perez! You might also want to
mention that MDE supports TeX rendering for all GUI widgets and text
boxes In support of the MDE, I offer an enhanced text box. This
one actually works decently, but still has a few lingering problems
* Trailing spaces are ignored in the calculation of the text size so
the cursor isn't always in the right position. This is relatively
easy to fix or approximate
* This example reveals a limitation in how mpl lays out text. The
vertical positions 'top', 'center', or 'bottom' apply to the text
bounding box. This can cause the whole text field to be raised or
lowered depending on what is typed. Very disconcerting. We'll
need a new flag, something like "baseline" to indicate that the y
position is the text baseline
* How to make the cursor blink? I tried writing a timer based on
the python threading module, but I don't think this plays nicely
with the mainloop. It might be work exposing the underlying gui
timers in the matplotlib gui abstraction layer.
For kicks, attached below is the screenshot I captured with this
examples enabling usetex in which I typed \alpha_i = \beta_j into the
textbox... It *worked* but caused some errors to be generated in
transit because the TeX was continuously compiled before the string
was complete..... Still a little work to be done..
from pylab import *
from matplotlib.transforms import lbwh_to_bbox, identity_transform
class TextBox(Widget):
def __init__(self, ax, s=''):
self.canvas = ax.figure.canvas
self.text = ax.text(0.025, 0.2, s,
fontsize=14,
verticalalignment='bottom',
horizontalalignment='left',
transform=ax.transAxes)
self.ax = ax
ax.set_yticks()
ax.set_xticks()
ax.set_navigate(False)
self.canvas.draw()
self.canvas.mpl_connect('key_press_event', self.keypress)
self.region = self.canvas.copy_from_bbox(ax.bbox)
r = self._get_text_right()
self.cursor, = ax.plot([r,r], [0.2, 0.8], transform=ax.transAxes)
self.redraw()
def redraw(self):
self.ax.redraw_in_frame()
self.canvas.blit(self.ax.bbox)
def keypress(self, event):
if event.key is not None and len(event.key)>1: return
t = self.text.get_text()
if event.key is None: # simulate backspace
if len(t): newt = t[:-1]
else: newt = ''
else:
newt = t + event.key
self.text.set_text(newt)
r = self._get_text_right()
self.cursor.set_xdata([r,r])
self.redraw()
def _get_text_right(self):
l,b,w,h = self.text.get_window_extent().get_bounds()
r = l+w+2
t = b+h
l,b = self.ax.transAxes.inverse_xy_tup((l,b))
r,t = self.ax.transAxes.inverse_xy_tup((r,t))
return r
ion()
f = figure()
ax = axes([0.1, 0.1, 0.8, 0.7])
plot([1,2,3])
#rc('text', usetex=1)
f.text(0.39, 0.875, 'My label: ',
horizontalalignment='right', verticalalignment='center')
axtext = axes([0.4, 0.85, 0.2, 0.05])
box = TextBox(axtext)
show()