Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e70217b

Browse files
HastingsGreerfariza
authored andcommitted
Added a text box example: evaluates any string inputs as y(x).
1 parent 80c20f3 commit e70217b

File tree

3 files changed

+106
-82
lines changed

3 files changed

+106
-82
lines changed

doc/users/whats_new.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
w.. _whats-new:
1+
.. _whats-new:
22

33
************************
44
What's new in matplotlib
@@ -245,8 +245,8 @@ Widgets
245245
-------
246246

247247
Added TextBox Widget
248-
249248
````````````````````
249+
250250
Added a widget that allows text entry by reading key events when it is active.
251251
Text caret in text box is visible when it is active, can be moved using arrow keys but not mouse
252252

examples/widgets/textbox.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
from matplotlib.widgets import TextBox
5+
fig, ax = plt.subplots()
6+
plt.subplots_adjust(bottom=0.2)
7+
t = np.arange(-2.0, 2.0, 0.001)
8+
s = t ** 2
9+
initial_text = "t ** 2"
10+
l, = plt.plot(t, s, lw=2)
11+
12+
13+
def submit(text):
14+
ydata = eval(text)
15+
l.set_ydata(ydata)
16+
ax.set_ylim(np.min(ydata), np.max(ydata))
17+
plt.draw()
18+
19+
axbox = plt.axes([0.1, 0.05, 0.8, 0.075])
20+
text_box = TextBox(axbox, 'Evaluate', initial=initial_text)
21+
text_box.on_submit(submit)
22+
23+
plt.show()

lib/matplotlib/widgets.py

Lines changed: 81 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -628,14 +628,14 @@ def disconnect(self, cid):
628628
except KeyError:
629629
pass
630630

631+
631632
class TextBox(AxesWidget):
632633
"""
633634
A GUI neutral text input box.
634635
635-
For the text box to remain responsive
636-
you must keep a reference to it.
636+
For the text box to remain responsive you must keep a reference to it.
637637
638-
The following attributes are accessible
638+
The following attributes are accessible:
639639
640640
*ax*
641641
The :class:`matplotlib.axes.Axes` the button renders into.
@@ -649,11 +649,13 @@ class TextBox(AxesWidget):
649649
*hovercolor*
650650
The color of the text box when hovering.
651651
652-
Call :meth:`on_text_change` to be updated whenever the text changes
653-
Call :meth:`on_submit` to be updated whenever the user hits enter or leaves the text entry field
652+
Call :meth:`on_text_change` to be updated whenever the text changes.
653+
654+
Call :meth:`on_submit` to be updated whenever the user hits enter or
655+
leaves the text entry field.
654656
"""
655657

656-
def __init__(self, ax, label, initial = '',
658+
def __init__(self, ax, label, initial='',
657659
color='.95', hovercolor='1'):
658660
"""
659661
Parameters
@@ -664,48 +666,48 @@ def __init__(self, ax, label, initial = '',
664666
665667
label : str
666668
Label for this text box. Accepts string.
667-
669+
668670
initial : str
669671
Initial value in the text box
670-
672+
671673
color : color
672674
The color of the box
673675
674676
hovercolor : color
675677
The color of the box when the mouse is over it
676678
"""
677679
AxesWidget.__init__(self, ax)
678-
679-
self.DIST_FROM_LEFT = .05
680-
680+
681+
self.DIST_FROM_LEFT = .05
682+
681683
self.params_to_disable = []
682-
for key in rcParams.keys():
684+
for key in rcParams.keys():
683685
if u'keymap' in key:
684-
self.params_to_disable += [key]
685-
686+
self.params_to_disable += [key]
687+
686688
self.text = initial
687-
688-
689-
690-
691-
self.label = ax.text(0.0,0.5, label,
689+
self.label = ax.text(0.0, 0.5, label,
692690
verticalalignment='center',
693691
horizontalalignment='right',
694692
transform=ax.transAxes)
695693
self.text_disp = self._make_text_disp(self.text)
696-
694+
697695
self.cnt = 0
698696
self.change_observers = {}
699697
self.submit_observers = {}
700-
701-
self.ax.set_xlim(0, 1) #If these lines are removed, the cursor won't appear
702-
self.ax.set_ylim(0, 1) #the first time the box is clicked
703-
704-
self.cursor_index = 0;
705-
self.cursor = self.ax.vlines(0, 0, 0) #because this is initialized, _render_cursor
706-
self.cursor.set_visible(False) #can assume that cursor exists
707-
708-
698+
699+
# If these lines are removed, the cursor won't appear the first
700+
# time the box is clicked:
701+
self.ax.set_xlim(0, 1)
702+
self.ax.set_ylim(0, 1)
703+
704+
self.cursor_index = 0
705+
706+
# Because this is initialized, _render_cursor
707+
# can assume that cursor exists.
708+
self.cursor = self.ax.vlines(0, 0, 0)
709+
self.cursor.set_visible(False)
710+
709711
self.connect_event('button_press_event', self._click)
710712
self.connect_event('button_release_event', self._release)
711713
self.connect_event('motion_notify_event', self._motion)
@@ -718,110 +720,107 @@ def __init__(self, ax, label, initial = '',
718720
self.hovercolor = hovercolor
719721

720722
self._lastcolor = color
721-
722-
self.capturekeystrokes = False
723-
724-
725723

726-
724+
self.capturekeystrokes = False
725+
727726
def _make_text_disp(self, string):
728727
return self.ax.text(self.DIST_FROM_LEFT, 0.5, string,
729-
verticalalignment='center',
730-
horizontalalignment='left',
731-
transform=self.ax.transAxes)
728+
verticalalignment='center',
729+
horizontalalignment='left',
730+
transform=self.ax.transAxes)
731+
732732
def _rendercursor(self):
733-
#this is a hack to figure out where the cursor should go.
734-
#we draw the text up to where the cursor should go, measure
735-
#save its dimensions, draw the real text, then put the cursor
736-
#at the saved dimensions
737-
733+
# this is a hack to figure out where the cursor should go.
734+
# we draw the text up to where the cursor should go, measure
735+
# save its dimensions, draw the real text, then put the cursor
736+
# at the saved dimensions
737+
738738
widthtext = self.text[:self.cursor_index]
739739
no_text = False
740740
if(widthtext == "" or widthtext == " " or widthtext == " "):
741741
no_text = widthtext == ""
742742
widthtext = ","
743-
744-
743+
745744
wt_disp = self._make_text_disp(widthtext)
746-
745+
747746
self.ax.figure.canvas.draw()
748747
bb = wt_disp.get_window_extent()
749748
inv = self.ax.transData.inverted()
750749
bb = inv.transform(bb)
751750
wt_disp.set_visible(False)
752751
if no_text:
753-
bb[1, 0] = bb[0, 0]
754-
#hack done
752+
bb[1, 0] = bb[0, 0]
753+
# hack done
755754
self.cursor.set_visible(False)
756-
757-
755+
758756
self.cursor = self.ax.vlines(bb[1, 0], bb[0, 1], bb[1, 1])
759757
self.ax.figure.canvas.draw()
760758

761759
def _notify_submit_observers(self):
762760
for cid, func in six.iteritems(self.submit_observers):
763761
func(self.text)
764-
762+
765763
def _release(self, event):
766764
if self.ignore(event):
767765
return
768766
if event.canvas.mouse_grabber != self.ax:
769767
return
770768
event.canvas.release_mouse(self.ax)
771-
769+
772770
def _keypress(self, event):
773771
if self.ignore(event):
774772
return
775773
if self.capturekeystrokes:
776774
key = event.key
777-
775+
778776
if(len(key) == 1):
779-
self.text = (self.text[:self.cursor_index] + key +
780-
self.text[self.cursor_index:])
781-
self.cursor_index += 1
777+
self.text = (self.text[:self.cursor_index] + key +
778+
self.text[self.cursor_index:])
779+
self.cursor_index += 1
782780
elif key == "right":
783-
if self.cursor_index != len(self.text):
784-
self.cursor_index += 1
781+
if self.cursor_index != len(self.text):
782+
self.cursor_index += 1
785783
elif key == "left":
786-
if self.cursor_index != 0:
787-
self.cursor_index -= 1
784+
if self.cursor_index != 0:
785+
self.cursor_index -= 1
788786
elif key == "home":
789-
self.cursor_index = 0
787+
self.cursor_index = 0
790788
elif key == "end":
791-
self.cursor_index = len(self.text)
789+
self.cursor_index = len(self.text)
792790
elif(key == "backspace"):
793791
if self.cursor_index != 0:
794-
self.text = (self.text[:self.cursor_index - 1] +
795-
self.text[self.cursor_index:])
792+
self.text = (self.text[:self.cursor_index - 1] +
793+
self.text[self.cursor_index:])
796794
self.cursor_index -= 1
797795
elif(key == "delete"):
798796
if self.cursor_index != len(self.text):
799-
self.text = (self.text[:self.cursor_index] +
800-
self.text[self.cursor_index + 1:])
797+
self.text = (self.text[:self.cursor_index] +
798+
self.text[self.cursor_index + 1:])
799+
801800
self.text_disp.remove()
802801
self.text_disp = self._make_text_disp(self.text)
803802
self._rendercursor()
804803
for cid, func in six.iteritems(self.change_observers):
805804
func(self.text)
806805
if key == "enter":
807-
self._notify_submit_observers()
808-
806+
self._notify_submit_observers()
807+
809808
def _click(self, event):
810809
if self.ignore(event):
811810
return
812811
if event.inaxes != self.ax:
813-
notifysubmit = False
814-
#because _notify_submit_users might throw an error in the
815-
#user's code, we only want to call it once we've already done
816-
#our cleanup.
812+
notifysubmit = False
813+
# because _notify_submit_users might throw an error in the
814+
# user's code, we only want to call it once we've already done
815+
# our cleanup.
817816
if self.capturekeystrokes:
818-
for key in self.params_to_disable:
817+
for key in self.params_to_disable:
819818
rcParams[key] = self.reset_params[key]
820-
notifysubmit = True
819+
notifysubmit = True
821820
self.capturekeystrokes = False
822821
self.cursor.set_visible(False)
823822
self.ax.figure.canvas.draw()
824-
823+
825824
if notifysubmit:
826825
self._notify_submit_observers()
827826
return
@@ -838,7 +837,6 @@ def _click(self, event):
838837
self.cursor_index = len(self.text)
839838
self._rendercursor()
840839

841-
842840
def _motion(self, event):
843841
if self.ignore(event):
844842
return
@@ -854,31 +852,35 @@ def _motion(self, event):
854852

855853
def on_text_change(self, func):
856854
"""
857-
When the text changes, call this *func* with event
855+
When the text changes, call this *func* with event.
858856
859-
A connection id is returned which can be used to disconnect
857+
A connection id is returned which can be used to disconnect.
860858
"""
861859
cid = self.cnt
862860
self.change_observers[cid] = func
863861
self.cnt += 1
864862
return cid
863+
865864
def on_submit(self, func):
866865
"""
867-
When the user hits enter or leaves the submision box, call this *func* with event
866+
When the user hits enter or leaves the submision box, call this
867+
*func* with event.
868868
869-
A connection id is returned which can be used to disconnect
869+
A connection id is returned which can be used to disconnect.
870870
"""
871871
cid = self.cnt
872872
self.submit_observers[cid] = func
873873
self.cnt += 1
874874
return cid
875+
875876
def disconnect(self, cid):
876877
"""remove the observer with connection id *cid*"""
877878
try:
878879
del self.observers[cid]
879880
except KeyError:
880881
pass
881882

883+
882884
class RadioButtons(AxesWidget):
883885
"""
884886
A GUI neutral radio button.
@@ -1176,7 +1178,6 @@ def funchspace(self, val):
11761178
self.targetfig.canvas.draw()
11771179

11781180

1179-
11801181
class Cursor(AxesWidget):
11811182
"""
11821183
A horizontal and vertical line that spans the axes and moves with

0 commit comments

Comments
 (0)