itrm 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {itrm-0.2.0/src/itrm.egg-info → itrm-0.2.2}/PKG-INFO +3 -2
- {itrm-0.2.0 → itrm-0.2.2}/README.md +2 -1
- {itrm-0.2.0 → itrm-0.2.2}/setup.cfg +1 -1
- {itrm-0.2.0 → itrm-0.2.2}/src/itrm/itrm.py +134 -45
- {itrm-0.2.0 → itrm-0.2.2/src/itrm.egg-info}/PKG-INFO +3 -2
- {itrm-0.2.0 → itrm-0.2.2}/LICENSE.txt +0 -0
- {itrm-0.2.0 → itrm-0.2.2}/pyproject.toml +0 -0
- {itrm-0.2.0 → itrm-0.2.2}/src/itrm/__init__.py +0 -0
- {itrm-0.2.0 → itrm-0.2.2}/src/itrm.egg-info/SOURCES.txt +0 -0
- {itrm-0.2.0 → itrm-0.2.2}/src/itrm.egg-info/dependency_links.txt +0 -0
- {itrm-0.2.0 → itrm-0.2.2}/src/itrm.egg-info/requires.txt +0 -0
- {itrm-0.2.0 → itrm-0.2.2}/src/itrm.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: itrm
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Interactive Terminal Utilities
|
|
5
5
|
Home-page: https://gitlab.com/davidwoodburn/itrm
|
|
6
6
|
Author: David Woodburn
|
|
@@ -59,7 +59,8 @@ call to `itrm`. The following table lists the configuration options:
|
|
|
59
59
|
| `ar` | `0.48` | aspect ratio of characters |
|
|
60
60
|
|
|
61
61
|
There is also a method for changing the color map: `itrm.config.cmap()`. It
|
|
62
|
-
takes a string: `"colors"`, `"grays"`, `"reds"`, `"greens"`, or
|
|
62
|
+
takes a string: `"colors"`, `"viridis"`, `"grays"`, `"reds"`, `"greens"`, or
|
|
63
|
+
`"blues"`.
|
|
63
64
|
|
|
64
65
|
## Interactive Plots
|
|
65
66
|
|
|
@@ -44,7 +44,8 @@ call to `itrm`. The following table lists the configuration options:
|
|
|
44
44
|
| `ar` | `0.48` | aspect ratio of characters |
|
|
45
45
|
|
|
46
46
|
There is also a method for changing the color map: `itrm.config.cmap()`. It
|
|
47
|
-
takes a string: `"colors"`, `"grays"`, `"reds"`, `"greens"`, or
|
|
47
|
+
takes a string: `"colors"`, `"viridis"`, `"grays"`, `"reds"`, `"greens"`, or
|
|
48
|
+
`"blues"`.
|
|
48
49
|
|
|
49
50
|
## Interactive Plots
|
|
50
51
|
|
|
@@ -37,16 +37,18 @@ import numpy as np
|
|
|
37
37
|
|
|
38
38
|
# Constants
|
|
39
39
|
# (blue, green, yellow, orange, magenta, purple)
|
|
40
|
-
DARK_COLORS
|
|
41
|
-
LITE_COLORS
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
DARK_COLORS = [ 33, 40, 220, 202, 201, 93]
|
|
41
|
+
LITE_COLORS = [ 75, 82, 228, 214, 213, 135]
|
|
42
|
+
DARK_VIRIDIS = [184, 113, 36, 30, 60, 53]
|
|
43
|
+
LITE_VIRIDIS = [227, 156, 79, 73, 103, 96]
|
|
44
|
+
DARK_GRAYS = [253, 250, 247, 244, 241, 238]
|
|
45
|
+
LITE_GRAYS = [255, 252, 249, 246, 243, 240]
|
|
46
|
+
DARK_REDS = [197, 196, 160, 124, 88, 52]
|
|
47
|
+
LITE_REDS = [198, 197, 196, 160, 124, 88]
|
|
48
|
+
DARK_GREENS = [ 47, 46, 40, 34, 28, 22]
|
|
49
|
+
LITE_GREENS = [ 48, 47, 46, 40, 34, 28]
|
|
50
|
+
DARK_BLUES = [ 27, 21, 20, 19, 18, 17]
|
|
51
|
+
LITE_BLUES = [ 33, 27, 21, 20, 19, 18]
|
|
50
52
|
COLOR_CNT = 6 # number of colors in the color map
|
|
51
53
|
eps = 1e-32 # minimum magnitude
|
|
52
54
|
|
|
@@ -58,13 +60,16 @@ class config: # configuration settings
|
|
|
58
60
|
ar = 0.48 # aspect ratio of characters
|
|
59
61
|
darks = DARK_COLORS # dark color map
|
|
60
62
|
lites = LITE_COLORS # light color map
|
|
61
|
-
|
|
63
|
+
|
|
62
64
|
def cmap(cmap="colors"):
|
|
63
65
|
if not isinstance(cmap, str):
|
|
64
66
|
raise ValueError(f"cmap must be a string: {cmap}")
|
|
65
67
|
if cmap == "colors":
|
|
66
68
|
config.darks = DARK_COLORS
|
|
67
69
|
config.lites = LITE_COLORS
|
|
70
|
+
elif cmap == "viridis":
|
|
71
|
+
config.darks = DARK_VIRIDIS
|
|
72
|
+
config.lites = LITE_VIRIDIS
|
|
68
73
|
elif cmap == "grays":
|
|
69
74
|
config.darks = DARK_GRAYS
|
|
70
75
|
config.lites = LITE_GRAYS
|
|
@@ -78,14 +83,16 @@ class config: # configuration settings
|
|
|
78
83
|
config.darks = DARK_BLUES
|
|
79
84
|
config.lites = LITE_BLUES
|
|
80
85
|
else:
|
|
81
|
-
raise ValueError(
|
|
82
|
-
+ "
|
|
86
|
+
raise ValueError('cmap must be one of '
|
|
87
|
+
+ '"colors", "viridis", "grays", '
|
|
88
|
+
+ '"reds", "greens", or "blues"')
|
|
83
89
|
|
|
84
90
|
|
|
85
91
|
class persistent: # persistent, run-time values
|
|
86
92
|
t_last = None # last time value
|
|
87
93
|
orig_term_attr = None # original terminal attributes
|
|
88
94
|
rows_last = None # last number of plot rows
|
|
95
|
+
tmp = 0.0
|
|
89
96
|
|
|
90
97
|
|
|
91
98
|
class limits: # x and y data limits
|
|
@@ -98,7 +105,6 @@ class limits: # x and y data limits
|
|
|
98
105
|
self.k_min = k_min # indices of minimum x
|
|
99
106
|
self.k_max = k_max # indices of maximum x
|
|
100
107
|
self.k_xc = k_xc # indices of x near cursor
|
|
101
|
-
self.tmp = 0.0
|
|
102
108
|
|
|
103
109
|
|
|
104
110
|
class term_ws: # terminal window size and sub-character resolution
|
|
@@ -415,8 +421,8 @@ def iplot(x, y=None, label=None, rows=1, cols=1, lg=None, overlay=False):
|
|
|
415
421
|
first = False
|
|
416
422
|
else:
|
|
417
423
|
if report:
|
|
418
|
-
rstr = view_str + f" < t:{tupdate:4f} >"
|
|
419
|
-
|
|
424
|
+
#rstr = view_str + f" < t:{tupdate:4f} >"
|
|
425
|
+
rstr = view_str + f" < {persistent.tmp} >" # FIXME
|
|
420
426
|
redraw_graph(C, D, F, row_zero, rstr, label,
|
|
421
427
|
ccol, cstr, cF, view, lims)
|
|
422
428
|
else:
|
|
@@ -645,7 +651,7 @@ def heat(matrix):
|
|
|
645
651
|
for row in range(0, (rows - rows%2), 2):
|
|
646
652
|
for col in range(cols):
|
|
647
653
|
print("\x1b[38;5;%dm\x1b[48;5;%dm\u2580" %
|
|
648
|
-
(M[row, col], M[row
|
|
654
|
+
(M[row, col], M[row+1, col]), end="", flush=True)
|
|
649
655
|
print("\x1b[0m", flush=True)
|
|
650
656
|
if rows % 2 == 1:
|
|
651
657
|
for col in range(cols):
|
|
@@ -1167,20 +1173,69 @@ def limits_xy(x, y, tws, equal_axes):
|
|
|
1167
1173
|
|
|
1168
1174
|
|
|
1169
1175
|
def get_row_zero(lims, tws):
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1176
|
+
"""
|
|
1177
|
+
Expand the limits to align zero with the nearest row so that the zero marker
|
|
1178
|
+
is true.
|
|
1179
|
+
"""
|
|
1180
|
+
|
|
1181
|
+
# Alias the current min and max y values.
|
|
1182
|
+
a = lims.y_min
|
|
1183
|
+
b = lims.y_max
|
|
1184
|
+
|
|
1185
|
+
if (a < 0) and (b > 0):
|
|
1186
|
+
# Get the real-valued and integer-valued center rows.
|
|
1187
|
+
C = tws.rows*b/(b-a) - 0.5
|
|
1188
|
+
Cl = math.floor(C) # lower value
|
|
1189
|
+
Ch = math.ceil(C) # higher value
|
|
1190
|
+
|
|
1191
|
+
# Get the scaling factors.
|
|
1192
|
+
kl = (Cl + 0.5)/tws.rows
|
|
1193
|
+
kh = (Ch + 0.5)/tws.rows
|
|
1194
|
+
|
|
1195
|
+
# Given the two scaling factors, get the new low values from fixed high
|
|
1196
|
+
# values and the new high values from fixed low values.
|
|
1197
|
+
Al = b*(kl - 1)/kl
|
|
1198
|
+
Ah = b*(kh - 1)/kh
|
|
1199
|
+
Bl = a*kl/(kl - 1)
|
|
1200
|
+
Bh = a*kh/(kh - 1)
|
|
1201
|
+
|
|
1202
|
+
# Between the two new low values, check which is at least as low as the
|
|
1203
|
+
# original.
|
|
1204
|
+
if Al <= a:
|
|
1205
|
+
A = Al
|
|
1206
|
+
CA = Cl
|
|
1207
|
+
elif Ah <= a:
|
|
1208
|
+
A = Ah
|
|
1209
|
+
CA = Ch
|
|
1210
|
+
else:
|
|
1211
|
+
A = -np.inf
|
|
1212
|
+
|
|
1213
|
+
# Between the two new high values, check which is at least as high as
|
|
1214
|
+
# the original.
|
|
1215
|
+
if Bl >= b:
|
|
1216
|
+
B = Bl
|
|
1217
|
+
CB = Cl
|
|
1218
|
+
elif Bh >= b:
|
|
1219
|
+
B = Bh
|
|
1220
|
+
CB = Ch
|
|
1221
|
+
else:
|
|
1222
|
+
B = np.inf
|
|
1223
|
+
|
|
1224
|
+
# Pick the pair which results in the smallest increase in range.
|
|
1225
|
+
if (b - A > 2*(b - a)) and (B - a > 2*(b - a)):
|
|
1226
|
+
row_zero = -1
|
|
1227
|
+
elif (b - A) < (B - a):
|
|
1228
|
+
lims.y_min = A
|
|
1229
|
+
lims.y_max = b
|
|
1230
|
+
row_zero = CA
|
|
1231
|
+
else:
|
|
1232
|
+
lims.y_min = a
|
|
1233
|
+
lims.y_max = B
|
|
1234
|
+
row_zero = CB
|
|
1182
1235
|
else:
|
|
1236
|
+
# Set the zero row to something invalid.
|
|
1183
1237
|
row_zero = -1
|
|
1238
|
+
|
|
1184
1239
|
return row_zero, lims
|
|
1185
1240
|
|
|
1186
1241
|
|
|
@@ -1234,8 +1289,8 @@ def data_to_matrix(x, y, view, tws, j_cursor):
|
|
|
1234
1289
|
# Scale the data to dots. First dot is 0; last dot is Cols - 1.
|
|
1235
1290
|
X = Cols*(x[j, mm] - view.x_min)/x_span - 0.5
|
|
1236
1291
|
Y = Rows*(view.y_max - y[j, mm])/y_span - 0.5
|
|
1237
|
-
X = np.clip(np.round(X).astype(int), 0, Cols
|
|
1238
|
-
Y = np.clip(np.round(Y).astype(int), 0, Rows
|
|
1292
|
+
X = np.clip(np.round(X).astype(int), 0, Cols-1)
|
|
1293
|
+
Y = np.clip(np.round(Y).astype(int), 0, Rows-1)
|
|
1239
1294
|
|
|
1240
1295
|
# Map locations to a large matrix.
|
|
1241
1296
|
M[Y, X] = 1 # Puts a 1 wherever the curve coordinates are.
|
|
@@ -1354,7 +1409,7 @@ def zoom_in_indices(x, view):
|
|
|
1354
1409
|
# Get subset of `x` within the old view.
|
|
1355
1410
|
ka = view.k_min[j]
|
|
1356
1411
|
kb = view.k_max[j]
|
|
1357
|
-
xj_view = x[j, ka:kb
|
|
1412
|
+
xj_view = x[j, ka:kb+1]
|
|
1358
1413
|
|
|
1359
1414
|
# Get the new index of minimum.
|
|
1360
1415
|
mm_min = (xj_view >= view.x_min).nonzero()[0]
|
|
@@ -1374,7 +1429,7 @@ def zoom_out_indices(x, view):
|
|
|
1374
1429
|
# Get subsets of `x` left or right of the old view.
|
|
1375
1430
|
kb = view.k_min[j]
|
|
1376
1431
|
ka = view.k_max[j]
|
|
1377
|
-
xj_left = x[j, :kb
|
|
1432
|
+
xj_left = x[j, :kb+1]
|
|
1378
1433
|
xj_right = x[j, ka:]
|
|
1379
1434
|
|
|
1380
1435
|
# Get the new index of minimum.
|
|
@@ -1396,17 +1451,17 @@ def pan_indices(x, view):
|
|
|
1396
1451
|
ka = view.k_min[j]
|
|
1397
1452
|
kb = view.k_max[j]
|
|
1398
1453
|
if (x[j, ka] >= view.x_min) and (x[j, kb] >= view.x_max): # <--
|
|
1399
|
-
xj_min = x[j, :ka
|
|
1400
|
-
xj_max = x[j, :kb
|
|
1454
|
+
xj_min = x[j, :ka+1]; k_min_ref = 0
|
|
1455
|
+
xj_max = x[j, :kb+1]; k_max_ref = 0
|
|
1401
1456
|
elif (x[j, ka] < view.x_min) and (x[j, kb] < view.x_max): # -->
|
|
1402
1457
|
xj_min = x[j, ka:]; k_min_ref = ka
|
|
1403
1458
|
xj_max = x[j, kb:]; k_max_ref = kb
|
|
1404
1459
|
elif (x[j, ka] >= view.x_min) and (x[j, kb] < view.x_max): # <->
|
|
1405
|
-
xj_min = x[j, :ka
|
|
1460
|
+
xj_min = x[j, :ka+1]; k_min_ref = 0
|
|
1406
1461
|
xj_max = x[j, kb:]; k_max_ref = kb
|
|
1407
1462
|
elif (x[j, ka] < view.x_min) and (x[j, kb] >= view.x_max): # >-<
|
|
1408
|
-
xj_min = x[j, ka:kb
|
|
1409
|
-
xj_max = x[j, ka:kb
|
|
1463
|
+
xj_min = x[j, ka:kb+1]; k_min_ref = ka
|
|
1464
|
+
xj_max = x[j, ka:kb+1]; k_max_ref = ka
|
|
1410
1465
|
|
|
1411
1466
|
# Get the new index of minimum.
|
|
1412
1467
|
mm_min = (xj_min >= view.x_min).nonzero()[0]
|
|
@@ -1427,7 +1482,7 @@ def center_view_x(xc, view):
|
|
|
1427
1482
|
def get_column(xc, view, tws):
|
|
1428
1483
|
x_span = view.x_max - view.x_min
|
|
1429
1484
|
ccol = round(tws.cols*(xc - view.x_min)/x_span - 0.5)
|
|
1430
|
-
ccol = min(max(ccol, 0), tws.cols
|
|
1485
|
+
ccol = min(max(ccol, 0), tws.cols-1)
|
|
1431
1486
|
return ccol
|
|
1432
1487
|
|
|
1433
1488
|
|
|
@@ -1447,8 +1502,8 @@ def get_cursor_y(x, y, view, tws, ccol, j_cursor):
|
|
|
1447
1502
|
for j in jj:
|
|
1448
1503
|
ka = view.k_min[j]
|
|
1449
1504
|
kb = view.k_max[j]
|
|
1450
|
-
xj_view = x[j, ka:kb
|
|
1451
|
-
yj_view = y[j, ka:kb
|
|
1505
|
+
xj_view = x[j, ka:kb+1]
|
|
1506
|
+
yj_view = y[j, ka:kb+1]
|
|
1452
1507
|
is_valid_x = np.isfinite(xj_view)
|
|
1453
1508
|
is_valid_y = np.isfinite(yj_view)
|
|
1454
1509
|
is_in = (xj_view >= xc_a) & (xj_view <= xc_b)
|
|
@@ -1479,8 +1534,8 @@ def get_view_y(x, y, view, j_cursor):
|
|
|
1479
1534
|
for j in jj:
|
|
1480
1535
|
ka = view.k_min[j]
|
|
1481
1536
|
kb = view.k_max[j]
|
|
1482
|
-
xj_view = x[j, ka:kb
|
|
1483
|
-
yj_view = y[j, ka:kb
|
|
1537
|
+
xj_view = x[j, ka:kb+1]
|
|
1538
|
+
yj_view = y[j, ka:kb+1]
|
|
1484
1539
|
is_valid_x = np.isfinite(xj_view)
|
|
1485
1540
|
is_valid_y = np.isfinite(yj_view)
|
|
1486
1541
|
mm = (is_valid_x & is_valid_y).nonzero()[0]
|
|
@@ -1552,7 +1607,7 @@ def matrix_to_ascii(M):
|
|
|
1552
1607
|
|
|
1553
1608
|
def matrix_to_stars(M):
|
|
1554
1609
|
I, J = M.shape
|
|
1555
|
-
C = 0x20*np.ones((I, 2*J
|
|
1610
|
+
C = 0x20*np.ones((I, 2*J+1), dtype=int)
|
|
1556
1611
|
C[:, 1:-1:2] += 0xA*M
|
|
1557
1612
|
return C
|
|
1558
1613
|
|
|
@@ -1723,7 +1778,7 @@ def redraw_graph(C, D, F=None, row_zero=-1, view_str=None, label=None,
|
|
|
1723
1778
|
x_view = (view.x_max + view.x_min)/2
|
|
1724
1779
|
col_center = round(cols*(x_view - lims.x_min)/x_span)
|
|
1725
1780
|
col_a = max(0, round(col_center - bar_width/2))
|
|
1726
|
-
col_b = min(cols
|
|
1781
|
+
col_b = min(cols-1, col_a + bar_width)
|
|
1727
1782
|
# Draw the bar.
|
|
1728
1783
|
print("\x1b[38;5;238m", end="", flush=True)
|
|
1729
1784
|
for col in range(cols):
|
|
@@ -1880,3 +1935,37 @@ def draw_bar(n, N, colorize, fat):
|
|
|
1880
1935
|
|
|
1881
1936
|
# Show the cursor.
|
|
1882
1937
|
print("\x1b[?25h", end="", flush=True)
|
|
1938
|
+
|
|
1939
|
+
|
|
1940
|
+
def viridis_map():
|
|
1941
|
+
"""
|
|
1942
|
+
Display the viridis color palette. The original RGB values came from
|
|
1943
|
+
https://waldyrious.net/viridis-palette-generator/.
|
|
1944
|
+
"""
|
|
1945
|
+
|
|
1946
|
+
# Input colors.
|
|
1947
|
+
vir = np.array([
|
|
1948
|
+
[253, 231, 37],
|
|
1949
|
+
[122, 209, 81],
|
|
1950
|
+
[34, 168, 132],
|
|
1951
|
+
[42, 120, 142],
|
|
1952
|
+
[65, 68, 135],
|
|
1953
|
+
[68, 1, 84]])
|
|
1954
|
+
|
|
1955
|
+
# Show dark colors.
|
|
1956
|
+
for n in range(6):
|
|
1957
|
+
r = int(5*vir[n, 0]/255)
|
|
1958
|
+
g = int(5*vir[n, 1]/255)
|
|
1959
|
+
b = int(5*vir[n, 2]/255)
|
|
1960
|
+
c = 16 + 36*r + 6*g + b
|
|
1961
|
+
print(f"\x1b[48;5;{c}m {c:03d} \x1b[0m ", end="")
|
|
1962
|
+
print()
|
|
1963
|
+
|
|
1964
|
+
# Show dark colors.
|
|
1965
|
+
for n in range(6):
|
|
1966
|
+
r = int(5*vir[n, 0]/255 + 1)
|
|
1967
|
+
g = int(5*vir[n, 1]/255 + 1)
|
|
1968
|
+
b = int(5*vir[n, 2]/255 + 1)
|
|
1969
|
+
c = 16 + 36*r + 6*g + b
|
|
1970
|
+
print(f"\x1b[48;5;{c}m {c:03d} \x1b[0m ", end="")
|
|
1971
|
+
print()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: itrm
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Interactive Terminal Utilities
|
|
5
5
|
Home-page: https://gitlab.com/davidwoodburn/itrm
|
|
6
6
|
Author: David Woodburn
|
|
@@ -59,7 +59,8 @@ call to `itrm`. The following table lists the configuration options:
|
|
|
59
59
|
| `ar` | `0.48` | aspect ratio of characters |
|
|
60
60
|
|
|
61
61
|
There is also a method for changing the color map: `itrm.config.cmap()`. It
|
|
62
|
-
takes a string: `"colors"`, `"grays"`, `"reds"`, `"greens"`, or
|
|
62
|
+
takes a string: `"colors"`, `"viridis"`, `"grays"`, `"reds"`, `"greens"`, or
|
|
63
|
+
`"blues"`.
|
|
63
64
|
|
|
64
65
|
## Interactive Plots
|
|
65
66
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|