3
3
import numpy as np
4
4
from larray_editor .utils import (get_font , from_qvariant , to_qvariant , to_text_string ,
5
5
is_float , is_number , LinearGradient , SUPPORTED_FORMATS , scale_to_01range ,
6
- Product )
6
+ Product , is_number_value , get_sample , get_sample_indices )
7
7
from qtpy .QtCore import Qt , QModelIndex , QAbstractTableModel
8
8
from qtpy .QtGui import QColor
9
9
from qtpy .QtWidgets import QMessageBox
@@ -256,8 +256,8 @@ def _set_data(self, data):
256
256
self ._compute_rows_cols_loaded ()
257
257
258
258
def reset_minmax (self ):
259
- data = self .get_values ()
260
259
try :
260
+ data = self .get_values (sample = True )
261
261
color_value = self .color_func (data ) if self .color_func is not None else data
262
262
# ignore nan, -inf, inf (setting them to 0 or to very large numbers is not an option)
263
263
color_value = color_value [np .isfinite (color_value )]
@@ -336,8 +336,21 @@ def data(self, index, role=Qt.DisplayRole):
336
336
elif role == Qt .BackgroundColorRole :
337
337
if self .bgcolor_possible and self .bg_gradient is not None and value is not np .ma .masked :
338
338
if self .bg_value is None :
339
- v = float (self .color_func (value ) if self .color_func is not None else value )
340
- v = scale_to_01range (v , self .vmin , self .vmax )
339
+ try :
340
+ v = self .color_func (value ) if self .color_func is not None else value
341
+ if - np .inf < v < self .vmin :
342
+ # TODO: this is suboptimal, as it can reset many times (though in practice, it is usually
343
+ # ok). When we get buffering, we will need to compute vmin/vmax on the whole buffer
344
+ # at once, eliminating this problem (and we could even compute final colors directly
345
+ # all at once)
346
+ self .vmin = v
347
+ self .reset ()
348
+ elif self .vmax < v < np .inf :
349
+ self .vmax = v
350
+ self .reset ()
351
+ v = scale_to_01range (v , self .vmin , self .vmax )
352
+ except TypeError :
353
+ v = np .nan
341
354
else :
342
355
i , j = index .row (), index .column ()
343
356
v = self .bg_value [i , j ]
@@ -346,26 +359,45 @@ def data(self, index, role=Qt.DisplayRole):
346
359
# return to_qvariant("{}\n{}".format(repr(value),self.get_labels(index)))
347
360
return to_qvariant ()
348
361
349
- def get_values (self , left = 0 , top = 0 , right = None , bottom = None ):
362
+ def get_values (self , left = 0 , top = 0 , right = None , bottom = None , sample = False ):
350
363
width , height = self .total_rows , self .total_cols
351
364
if right is None :
352
365
right = width
353
366
if bottom is None :
354
367
bottom = height
355
- values = self . _data [ left : right , top : bottom ]. copy ()
356
- # both versions get the same result, but depending on inputs, the
357
- # speed difference can be large.
368
+ # this whole bullshit will disappear when we implement undo/redo
369
+ values = self . _data [ left : right , top : bottom ]
370
+ # both versions get the same result, but depending on inputs, the speed difference can be large.
358
371
if values .size < len (self .changes ):
372
+ # changes are supposedly relatively small so this case should not be too slow even if we just want a sample
373
+ values = values .copy ()
359
374
for i in range (left , right ):
360
375
for j in range (top , bottom ):
361
376
pos = i , j
362
377
if pos in self .changes :
363
378
values [i - left , j - top ] = self .changes [pos ]
379
+ if sample :
380
+ return get_sample (values , 500 )
381
+ else :
382
+ return values
364
383
else :
365
- for (i , j ), value in self .changes .items ():
366
- if left <= i < right and top <= j < bottom :
367
- values [i - left , j - top ] = value
368
- return values
384
+ if sample :
385
+ sample_indices = get_sample_indices (values , 500 )
386
+ changes = self .changes
387
+
388
+ def get_val (idx ):
389
+ i , j = idx
390
+ changes_idx = (i + left , j + top )
391
+ return changes [changes_idx ] if changes_idx in changes else values [idx ]
392
+
393
67E6
td>+ # we need to keep the dtype, otherwise numpy might convert mixed object arrays to strings
394
+ return np .array ([get_val (idx ) for idx in zip (* sample_indices )], dtype = values .dtype )
395
+ else :
396
+ values = values .copy ()
397
+ for (i , j ), value in self .changes .items ():
398
+ if left <= i < right and top <= j < bottom :
399
+ values [i - left , j - top ] = value
400
+ return values
369
401
370
402
def convert_value (self , value ):
371
403
"""
0 commit comments