Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/tqdm/gui.py: 91%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Matplotlib GUI progressbar decorator for iterators.
4Usage:
5>>> from tqdm.gui import trange, tqdm
6>>> for i in trange(10):
7... ...
8"""
9# future division is important to divide integers and get as
10# a result precise floating numbers (instead of truncated int)
11import re
12from warnings import warn
14# to inherit from the tqdm class
15from .std import TqdmExperimentalWarning
16from .std import tqdm as std_tqdm
18# import compatibility functions and utilities
20__author__ = {"github.com/": ["casperdcl", "lrq3000"]}
21__all__ = ['tqdm_gui', 'tgrange', 'tqdm', 'trange']
24class tqdm_gui(std_tqdm): # pragma: no cover
25 """Experimental Matplotlib GUI version of tqdm!"""
26 # TODO: @classmethod: write() on GUI?
27 def __init__(self, *args, **kwargs):
28 from collections import deque
30 import matplotlib as mpl
31 import matplotlib.pyplot as plt
32 kwargs = kwargs.copy()
33 kwargs['gui'] = True
34 colour = kwargs.pop('colour', 'g')
35 super().__init__(*args, **kwargs)
37 if self.disable:
38 return
40 warn("GUI is experimental/alpha", TqdmExperimentalWarning, stacklevel=2)
41 self.mpl = mpl
42 self.plt = plt
44 # Remember if external environment uses toolbars
45 self.toolbar = self.mpl.rcParams['toolbar']
46 self.mpl.rcParams['toolbar'] = 'None'
48 self.mininterval = max(self.mininterval, 0.5)
49 self.fig, ax = plt.subplots(figsize=(9, 2.2))
50 # self.fig.subplots_adjust(bottom=0.2)
51 total = self.__len__() # avoids TypeError on None #971
52 if total is not None:
53 self.xdata = []
54 self.ydata = []
55 self.zdata = []
56 else:
57 self.xdata = deque([])
58 self.ydata = deque([])
59 self.zdata = deque([])
60 self.line1, = ax.plot(self.xdata, self.ydata, color='b')
61 self.line2, = ax.plot(self.xdata, self.zdata, color='k')
62 ax.set_ylim(0, 0.001)
63 if total is not None:
64 ax.set_xlim(0, 100)
65 ax.set_xlabel("percent")
66 self.fig.legend((self.line1, self.line2), ("cur", "est"),
67 loc='center right')
68 # progressbar
69 self.hspan = plt.axhspan(0, 0.001, xmin=0, xmax=0, color=colour)
70 else:
71 # ax.set_xlim(-60, 0)
72 ax.set_xlim(0, 60)
73 ax.invert_xaxis()
74 ax.set_xlabel("seconds")
75 ax.legend(("cur", "est"), loc='lower left')
76 ax.grid()
77 # ax.set_xlabel('seconds')
78 ax.set_ylabel((self.unit if self.unit else "it") + "/s")
79 if self.unit_scale:
80 plt.ticklabel_format(style='sci', axis='y', scilimits=(0, 0))
81 ax.yaxis.get_offset_text().set_x(-0.15)
83 # Remember if external environment is interactive
84 self.wasion = plt.isinteractive()
85 plt.ion()
86 self.ax = ax
88 def close(self):
89 if self.disable:
90 return
92 self.disable = True
94 with self.get_lock():
95 self._instances.remove(self)
97 # Restore toolbars
98 self.mpl.rcParams['toolbar'] = self.toolbar
99 # Return to non-interactive mode
100 if not self.wasion:
101 self.plt.ioff()
102 if self.leave:
103 self.display()
104 else:
105 self.plt.close(self.fig)
107 def clear(self, *_, **__):
108 pass
110 def display(self, *_, **__):
111 n = self.n
112 cur_t = self._time()
113 elapsed = cur_t - self.start_t
114 delta_it = n - self.last_print_n
115 delta_t = cur_t - self.last_print_t
117 # Inline due to multiple calls
118 total = self.total
119 xdata = self.xdata
120 ydata = self.ydata
121 zdata = self.zdata
122 ax = self.ax
123 line1 = self.line1
124 line2 = self.line2
125 hspan = getattr(self, 'hspan', None)
126 # instantaneous rate
127 y = delta_it / delta_t
128 # overall rate
129 z = n / elapsed
130 # update line data
131 xdata.append(n * 100.0 / total if total else cur_t)
132 ydata.append(y)
133 zdata.append(z)
135 # Discard old values
136 # xmin, xmax = ax.get_xlim()
137 # if (not total) and elapsed > xmin * 1.1:
138 if (not total) and elapsed > 66:
139 xdata.popleft()
140 ydata.popleft()
141 zdata.popleft()
143 ymin, ymax = ax.get_ylim()
144 if y > ymax or z > ymax:
145 ymax = 1.1 * y
146 ax.set_ylim(ymin, ymax)
147 ax.figure.canvas.draw()
149 if total:
150 line1.set_data(xdata, ydata)
151 line2.set_data(xdata, zdata)
152 if hspan:
153 hspan.set_xy((0, ymin))
154 hspan.set_height(ymax - ymin)
155 hspan.set_width(n / total)
156 else:
157 t_ago = [cur_t - i for i in xdata]
158 line1.set_data(t_ago, ydata)
159 line2.set_data(t_ago, zdata)
161 d = self.format_dict
162 # remove {bar}
163 d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace(
164 "{bar}", "<bar/>")
165 msg = self.format_meter(**d)
166 if '<bar/>' in msg:
167 msg = "".join(re.split(r'\|?<bar/>\|?', msg, maxsplit=1))
168 ax.set_title(msg, fontname="DejaVu Sans Mono", fontsize=11)
169 self.plt.pause(1e-9)
172def tgrange(*args, **kwargs):
173 """Shortcut for `tqdm.gui.tqdm(range(*args), **kwargs)`."""
174 return tqdm_gui(range(*args), **kwargs)
177# Aliases
178tqdm = tqdm_gui
179trange = tgrange