mwxlib 1.6.10__py3-none-any.whl → 1.7.0__py3-none-any.whl

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.

Potentially problematic release.


This version of mwxlib might be problematic. Click here for more details.

mwx/matplot2g.py CHANGED
@@ -60,7 +60,7 @@ def _to_buffer(img):
60
60
 
61
61
 
62
62
  def _to_image(src, cutoff=0, threshold=None, binning=1):
63
- """Convert buffer to image <uint8>
63
+ """Convert buffer to image <uint8>.
64
64
 
65
65
  >>> dst = (src-a) * 255 / (b-a)
66
66
 
@@ -116,7 +116,7 @@ def _Property(name):
116
116
 
117
117
 
118
118
  class AxesImagePhantom:
119
- """Phantom of frame facade
119
+ """Phantom of frame facade.
120
120
 
121
121
  Args:
122
122
  buf: buffer
@@ -150,14 +150,14 @@ class AxesImagePhantom:
150
150
  picker = True,
151
151
  )
152
152
  self.update_extent()
153
-
153
+
154
154
  def __getattr__(self, attr):
155
155
  return getattr(self.__art, attr)
156
-
156
+
157
157
  def __eq__(self, x):
158
158
  ## Called in `on_pick` and `__contains__` to check objects in.
159
159
  return x is self.__art
160
-
160
+
161
161
  def update_attr(self, attr):
162
162
  """Update frame-specifc attributes:
163
163
 
@@ -183,7 +183,7 @@ class AxesImagePhantom:
183
183
 
184
184
  if {'pathname', 'annotation'} & attr.keys():
185
185
  self.parent.handler('frame_updated', self)
186
-
186
+
187
187
  def update_buffer(self, buf=None):
188
188
  """Update buffer and the image (internal use only)."""
189
189
  if buf is not None:
@@ -197,7 +197,7 @@ class AxesImagePhantom:
197
197
  self.__cuts = vlim
198
198
  self.__art.set_array(img)
199
199
  self.parent.handler('frame_modified', self)
200
-
200
+
201
201
  def update_extent(self):
202
202
  """Update logical extent of the image (internal use only)."""
203
203
  h, w = self.__buf.shape[:2]
@@ -206,59 +206,59 @@ class AxesImagePhantom:
206
206
  h *= uy/2
207
207
  cx, cy = self.center
208
208
  self.__art.set_extent((cx-w, cx+w, cy-h, cy+h))
209
-
209
+
210
210
  artist = property(
211
211
  lambda self: self.__art)
212
-
212
+
213
213
  binning = property(
214
214
  lambda self: self.__bins,
215
215
  doc="Binning value resulting from the score_percentile.")
216
-
216
+
217
217
  cuts = property(
218
218
  lambda self: self.__cuts,
219
219
  doc="Lower/Upper cutoff values of the buffer.")
220
-
220
+
221
221
  image = property(
222
222
  lambda self: self.__art.get_array(),
223
223
  doc="Displayed image array<uint8>.")
224
-
224
+
225
225
  clim = property(
226
226
  lambda self: self.__art.get_clim(),
227
227
  lambda self, v: self.__art.set_clim(v),
228
228
  doc="Lower/Upper color limit values of the buffer.")
229
-
229
+
230
230
  attributes = property(
231
231
  lambda self: self.__attributes,
232
232
  doc="Auxiliary info about the frame.")
233
-
233
+
234
234
  pathname = property(
235
235
  lambda self: self.__attributes.get('pathname'),
236
236
  lambda self, v: self.update_attr({'pathname': v}),
237
237
  doc="Fullpath of the buffer, if bound to a file.")
238
-
238
+
239
239
  annotation = property(
240
240
  lambda self: self.__attributes.get('annotation', ''),
241
241
  lambda self, v: self.update_attr({'annotation': v}),
242
242
  doc="Annotation of the buffer.")
243
-
243
+
244
244
  @property
245
245
  def name(self):
246
246
  return self.__name
247
-
247
+
248
248
  @name.setter
249
249
  def name(self, v):
250
250
  self.__name = v
251
251
  self.parent.handler('frame_updated', self)
252
-
252
+
253
253
  @property
254
254
  def localunit(self):
255
255
  return self.__localunit
256
-
256
+
257
257
  @property
258
258
  def unit(self):
259
259
  """Logical length per pixel arb.unit [u/pix]."""
260
260
  return self.__localunit or self.parent.unit
261
-
261
+
262
262
  @unit.setter
263
263
  def unit(self, v):
264
264
  if v == self.__localunit: # no effect
@@ -275,44 +275,44 @@ class AxesImagePhantom:
275
275
  self.update_extent()
276
276
  self.parent.handler('frame_updated', self)
277
277
  self.parent.canvas.draw_idle()
278
-
278
+
279
279
  @unit.deleter
280
280
  def unit(self):
281
281
  self.unit = None
282
-
282
+
283
283
  @property
284
284
  def xy_unit(self):
285
285
  u = self.__localunit or self.parent.unit
286
286
  return (u, u * self.__aspect_ratio)
287
-
287
+
288
288
  @property
289
289
  def center(self):
290
290
  """Center of logical unit."""
291
291
  return self.__center
292
-
292
+
293
293
  @center.setter
294
294
  def center(self, v):
295
295
  self.__center = tuple(v)
296
296
  self.__attributes['center'] = self.__center
297
297
  self.update_extent()
298
298
  self.parent.handler('frame_updated', self)
299
-
299
+
300
300
  @property
301
301
  def aspect_ratio(self):
302
302
  """Aspect ratio of logical unit."""
303
303
  return self.__aspect_ratio
304
-
304
+
305
305
  @aspect_ratio.setter
306
306
  def aspect_ratio(self, v):
307
307
  self.__aspect_ratio = v or 1
308
308
  self.update_extent()
309
309
  self.parent.handler('frame_updated', self)
310
-
310
+
311
311
  @property
312
312
  def index(self):
313
313
  """Page number in the parent view."""
314
314
  return self.parent.index(self)
315
-
315
+
316
316
  @property
317
317
  def roi(self):
318
318
  """Current buffer ROI (region of interest)."""
@@ -322,27 +322,27 @@ class AxesImagePhantom:
322
322
  sy = slice(max(0, ny[1]), ny[0]) # ny slice 反転 (降順)
323
323
  return self.__buf[sy, sx]
324
324
  return None
325
-
325
+
326
326
  @roi.setter
327
327
  def roi(self, v):
328
328
  if not self.parent.region.size:
329
329
  raise ValueError("region is not selected.")
330
330
  self.roi[:] = v # cannot broadcast input array into different shape
331
331
  self.update_buffer()
332
-
332
+
333
333
  @property
334
334
  def roi_or_buffer(self):
335
335
  return self.roi if self.parent.region.size else self.buffer
336
-
336
+
337
337
  @property
338
338
  def buffer(self):
339
339
  return self.__buf
340
-
340
+
341
341
  @buffer.setter
342
342
  def buffer(self, v):
343
343
  self.update_buffer(v)
344
344
  self.update_extent()
345
-
345
+
346
346
  def xytoc(self, x, y=None, nearest=True):
347
347
  """Convert xydata (x,y) -> data[(x,y)] value of neaerst pixel.
348
348
  If `nearest` is False, the return value is interpolated with spline.
@@ -355,7 +355,7 @@ class AxesImagePhantom:
355
355
  if nearest:
356
356
  return self.__buf[ny, nx] # nearest value
357
357
  return ndi.map_coordinates(self.__buf, np.vstack((ny, nx))) # spline value
358
-
358
+
359
359
  def xytopixel(self, x, y=None, cast=True):
360
360
  """Convert xydata (x,y) -> [nx,ny] pixel.
361
361
  If `cast` is True, the return value will be integer pixel values.
@@ -373,7 +373,7 @@ class AxesImagePhantom:
373
373
  if cast:
374
374
  return np.array((_cast(nx), _cast(ny)))
375
375
  return np.array((nx-0.5, ny-0.5))
376
-
376
+
377
377
  def xyfrompixel(self, nx, ny=None):
378
378
  """Convert pixel [nx,ny] -> (x,y) xydata (float number).
379
379
  """
@@ -386,53 +386,53 @@ class AxesImagePhantom:
386
386
  x = l + (nx + 0.5) * ux
387
387
  y = t - (ny + 0.5) * uy # Y ピクセルインデクスは座標と逆
388
388
  return np.array((x, y))
389
-
389
+
390
390
  selector = _Property('selector')
391
391
  markers = _Property('markers')
392
392
  region = _Property('region')
393
-
393
+
394
394
  @property
395
395
  def selector_pix(self):
396
396
  """Selected points array [[x],[y]] in pixels."""
397
397
  return self.xytopixel(self.selector)
398
-
398
+
399
399
  @selector_pix.setter
400
400
  def selector_pix(self, v):
401
401
  self.selector = self.xyfrompixel(v)
402
-
402
+
403
403
  @selector_pix.deleter
404
404
  def selector_pix(self):
405
405
  del self.selector
406
-
406
+
407
407
  @property
408
408
  def markers_pix(self):
409
409
  """Marked points data array [[x],[y]] in pixels."""
410
410
  return self.xytopixel(self.markers)
411
-
411
+
412
412
  @markers_pix.setter
413
413
  def markers_pix(self, v):
414
414
  self.markers = self.xyfrompixel(v)
415
-
415
+
416
416
  @markers_pix.deleter
417
417
  def markers_pix(self):
418
418
  del self.markers
419
-
419
+
420
420
  @property
421
421
  def region_pix(self):
422
422
  """Cropped points data array [l,r],[b,t] in pixels."""
423
423
  return self.xytopixel(self.region)
424
-
424
+
425
425
  @region_pix.setter
426
426
  def region_pix(self, v):
427
427
  self.region = self.xyfrompixel(v)
428
-
428
+
429
429
  @region_pix.deleter
430
430
  def region_pix(self):
431
431
  del self.region
432
432
 
433
433
 
434
434
  class GraphPlot(MatplotPanel):
435
- """Graph panel for 2D graph
435
+ """Graph panel for 2D graph.
436
436
  """
437
437
  def __init__(self, *args, **kwargs):
438
438
  MatplotPanel.__init__(self, *args, **kwargs)
@@ -636,7 +636,7 @@ class GraphPlot(MatplotPanel):
636
636
  self.Layout()
637
637
 
638
638
  self.writeln()
639
-
639
+
640
640
  def clear(self):
641
641
  MatplotPanel.clear(self)
642
642
 
@@ -663,7 +663,7 @@ class GraphPlot(MatplotPanel):
663
663
  self.__isPicked = None
664
664
  self.selected.set_picker(8)
665
665
  self.selected.set_clip_on(False)
666
-
666
+
667
667
  def get_uniqname(self, name):
668
668
  base = name = name or "*temp*"
669
669
  i = 1
@@ -672,7 +672,7 @@ class GraphPlot(MatplotPanel):
672
672
  i += 1
673
673
  name = "{}<{:d}>".format(base, i)
674
674
  return name
675
-
675
+
676
676
  def load(self, buf, name=None, pos=None, show=True, **kwargs):
677
677
  """Load a buffer with a name.
678
678
 
@@ -721,7 +721,7 @@ class GraphPlot(MatplotPanel):
721
721
  if u != art.unit:
722
722
  self.axes.axis(art.get_extent())
723
723
  return art
724
-
724
+
725
725
  def select(self, index):
726
726
  if isinstance(index, (str, AxesImagePhantom)):
727
727
  j = self.index(index)
@@ -746,11 +746,11 @@ class GraphPlot(MatplotPanel):
746
746
  self.writeln()
747
747
  self.trace_point(*self.selector)
748
748
  return self.frame
749
-
749
+
750
750
  def __iter__(self):
751
751
  for art in self.__Arts:
752
752
  yield art.buffer
753
-
753
+
754
754
  def __getitem__(self, j):
755
755
  if isinstance(j, str):
756
756
  j = self.index(j)
@@ -759,7 +759,7 @@ class GraphPlot(MatplotPanel):
759
759
  if hasattr(j, '__iter__'):
760
760
  return [buffers[i] for i in j]
761
761
  return buffers[j] # j can also be slicing
762
-
762
+
763
763
  def __setitem__(self, j, v):
764
764
  if v is None:
765
765
  raise ValueError("values must be buffers, not NoneType")
@@ -774,7 +774,7 @@ class GraphPlot(MatplotPanel):
774
774
  art.update_buffer(v) # update buffer
775
775
  art.update_extent()
776
776
  self.select(j)
777
-
777
+
778
778
  def __delitem__(self, j):
779
779
  if isinstance(j, str):
780
780
  j = self.index(j)
@@ -798,19 +798,19 @@ class GraphPlot(MatplotPanel):
798
798
  n = len(self)
799
799
  self.__index = None if n==0 else j if j<n else n-1
800
800
  self.select(self.__index)
801
-
801
+
802
802
  ## __len__ は bool() でも呼び出されるため,オブジェクト判定で偽を返すことがある (PY2)
803
803
  ## __nonzero__ : bool() を追加しておく必要がある (PY2)
804
-
804
+
805
805
  def __len__(self):
806
806
  return len(self.__Arts)
807
-
807
+
808
808
  def __nonzero__(self):
809
809
  return True
810
-
810
+
811
811
  def __bool__(self):
812
812
  return True
813
-
813
+
814
814
  def __contains__(self, j):
815
815
  if isinstance(j, str):
816
816
  return j in (art.name for art in self.__Arts)
@@ -818,7 +818,7 @@ class GraphPlot(MatplotPanel):
818
818
  return any(j is art.buffer for art in self.__Arts)
819
819
  else:
820
820
  return j in self.__Arts
821
-
821
+
822
822
  def index(self, j):
823
823
  if isinstance(j, str):
824
824
  return next(i for i, art in enumerate(self.__Arts) if j == art.name)
@@ -826,7 +826,7 @@ class GraphPlot(MatplotPanel):
826
826
  return next(i for i, art in enumerate(self.__Arts) if j is art.buffer)
827
827
  else:
828
828
  return self.__Arts.index(j) # j:frame -> int
829
-
829
+
830
830
  def find_frame(self, j):
831
831
  if isinstance(j, str):
832
832
  return next((art for art in self.__Arts if j == art.name), None)
@@ -834,7 +834,7 @@ class GraphPlot(MatplotPanel):
834
834
  return next((art for art in self.__Arts if j is art.buffer), None)
835
835
  else:
836
836
  return self.__Arts[j] # j:int -> frame
837
-
837
+
838
838
  def get_all_frames(self, j=None):
839
839
  """List of arts <matplotlib.image.AxesImage>."""
840
840
  if j is None:
@@ -843,46 +843,46 @@ class GraphPlot(MatplotPanel):
843
843
  yield from (art for art in self.__Arts if j in art.name)
844
844
  elif isinstance(j, np.ndarray):
845
845
  yield from (art for art in self.__Arts if j is art.buffer)
846
-
846
+
847
847
  ## --------------------------------
848
848
  ## Property of frame / drawer
849
849
  ## --------------------------------
850
-
850
+
851
851
  #: image bytes max for loading matplotlib (with wxAgg backend)
852
852
  nbytes_threshold = 24e6
853
-
853
+
854
854
  #: image cutoff score percentiles
855
855
  score_percentile = 0.005
856
-
856
+
857
857
  @property
858
858
  def all_frames(self):
859
859
  """List of arts <matplotlib.image.AxesImage>."""
860
860
  return self.__Arts
861
-
861
+
862
862
  @property
863
863
  def frame(self):
864
864
  """Current art <matplotlib.image.AxesImage>."""
865
865
  if self.__Arts and self.__index is not None:
866
866
  return self.__Arts[self.__index]
867
-
867
+
868
868
  @property
869
869
  def buffer(self):
870
870
  """Current buffer array."""
871
871
  if self.frame:
872
872
  return self.frame.buffer
873
-
873
+
874
874
  @buffer.setter
875
875
  def buffer(self, v):
876
876
  if self.frame:
877
877
  self.__setitem__(self.__index, v)
878
878
  else:
879
879
  self.load(v)
880
-
880
+
881
881
  @property
882
882
  def unit(self):
883
883
  """Logical length per pixel arb.unit [u/pix]."""
884
884
  return self.__unit
885
-
885
+
886
886
  @unit.setter
887
887
  def unit(self, v):
888
888
  if v == self.__unit: # no effect unless unit changes
@@ -897,14 +897,14 @@ class GraphPlot(MatplotPanel):
897
897
  art.update_extent()
898
898
  self.handler('frame_updated', art)
899
899
  self.canvas.draw_idle()
900
-
900
+
901
901
  def kill_buffer(self):
902
902
  if self.frame:
903
903
  del self[self.__index]
904
-
904
+
905
905
  def kill_buffer_all(self):
906
906
  del self[:]
907
-
907
+
908
908
  def fit_to_axes(self):
909
909
  """Reset the view limits to the current frame extent."""
910
910
  if self.frame:
@@ -912,7 +912,7 @@ class GraphPlot(MatplotPanel):
912
912
  self.toolbar.update()
913
913
  self.toolbar.push_current()
914
914
  self.draw()
915
-
915
+
916
916
  def fit_to_canvas(self):
917
917
  """Reset the view limits to the canvas range."""
918
918
  x, y = self.xlim, self.ylim
@@ -928,7 +928,7 @@ class GraphPlot(MatplotPanel):
928
928
  dy = (x[1] - x[0]) / 2 * r
929
929
  self.ylim = cy-dy, cy+dy
930
930
  self.draw()
931
-
931
+
932
932
  def on_focus_set(self, evt):
933
933
  """Called when focus is set (override)."""
934
934
  MatplotPanel.on_focus_set(self, evt)
@@ -936,30 +936,30 @@ class GraphPlot(MatplotPanel):
936
936
  self.handler('frame_selected', self.frame)
937
937
  self.on_picker_unlock(evt)
938
938
  self.trace_point(*self.selector)
939
-
939
+
940
940
  def on_focus_kill(self, evt):
941
941
  """Called when focus is killed (override)."""
942
942
  MatplotPanel.on_focus_kill(self, evt)
943
943
  if self.frame:
944
944
  self.handler('frame_deselected', self.frame)
945
945
  self.on_picker_lock(evt)
946
-
946
+
947
947
  def get_cmapstr(self):
948
948
  if self.frame:
949
949
  return self.frame.get_cmap().name
950
950
  return ''
951
-
951
+
952
952
  def set_cmapstr(self, name):
953
953
  if self.frame:
954
954
  self.frame.set_cmap(name)
955
955
  self.handler('frame_cmapped', self.frame)
956
956
  self.draw()
957
-
957
+
958
958
  def invert_cmap(self):
959
959
  if self.frame:
960
960
  name = self.frame.get_cmap().name
961
961
  self.set_cmapstr(name + "_r" if name[-2:] != "_r" else name[:-2])
962
-
962
+
963
963
  def trace_point(self, x, y, type=NORMAL):
964
964
  """Puts (override) a message of points x and y."""
965
965
  frame = self.frame
@@ -990,7 +990,7 @@ class GraphPlot(MatplotPanel):
990
990
  xo, yo = min(nx), min(ny) # top-left
991
991
  xr, yr = max(nx), max(ny) # bottom-right
992
992
  self.message(f"[Region] crop={xr-xo}:{yr-yo}:{xo}:{yo}") # (W:H:left:top)
993
-
993
+
994
994
  def writeln(self):
995
995
  """Puts (override) attributes of current frame to the modeline."""
996
996
  if not self.modeline.IsShown():
@@ -1015,14 +1015,14 @@ class GraphPlot(MatplotPanel):
1015
1015
  page = '-',
1016
1016
  maxpage = len(self),
1017
1017
  unit = self.__unit))
1018
-
1018
+
1019
1019
  ## --------------------------------
1020
1020
  ## 外部入出力/複合インターフェース
1021
1021
  ## --------------------------------
1022
1022
  ## GraphPlot 間共有のグローバル変数
1023
1023
  clipboard_name = None
1024
1024
  clipboard_data = None
1025
-
1025
+
1026
1026
  def write_buffer_to_clipboard(self):
1027
1027
  """Write buffer data to clipboard."""
1028
1028
  frame = self.frame
@@ -1037,7 +1037,7 @@ class GraphPlot(MatplotPanel):
1037
1037
  bins, vlim, img = _to_image(data, frame.cuts)
1038
1038
  Clipboard.imwrite(img)
1039
1039
  self.message("Write buffer to clipboard.")
1040
-
1040
+
1041
1041
  def read_buffer_from_clipboard(self):
1042
1042
  """Read buffer data from clipboard."""
1043
1043
  name = GraphPlot.clipboard_name
@@ -1051,7 +1051,7 @@ class GraphPlot(MatplotPanel):
1051
1051
  data = Clipboard.imread()
1052
1052
  if data is not None:
1053
1053
  self.load(data)
1054
-
1054
+
1055
1055
  def destroy_colorbar(self):
1056
1056
  if self.cbar:
1057
1057
  self.cbar = None
@@ -1060,13 +1060,13 @@ class GraphPlot(MatplotPanel):
1060
1060
  self.canvas.draw_idle()
1061
1061
  self.handler.unbind('frame_cmapped', self.update_colorbar)
1062
1062
  self.handler.unbind('frame_shown', self.update_colorbar)
1063
-
1063
+
1064
1064
  def update_colorbar(self, frame):
1065
1065
  if self.cbar:
1066
1066
  self.cbar.update_normal(frame)
1067
1067
  self.canvas.draw_idle()
1068
1068
  self.figure.draw_without_rendering()
1069
-
1069
+
1070
1070
  def create_colorbar(self):
1071
1071
  """Make a colorbar.
1072
1072
  The colorbar is plotted in self.figure.axes[1] (second axes)
@@ -1081,11 +1081,11 @@ class GraphPlot(MatplotPanel):
1081
1081
  self.handler.bind('frame_shown', self.update_colorbar)
1082
1082
  else:
1083
1083
  self.message("- A frame must exist to create a colorbar.")
1084
-
1084
+
1085
1085
  ## --------------------------------
1086
1086
  ## matplotlib interfaces
1087
1087
  ## --------------------------------
1088
-
1088
+
1089
1089
  def on_pick(self, evt): #<matplotlib.backend_bases.PickEvent>
1090
1090
  """Pickup image and other arts.
1091
1091
  Called (maybe) after mouse buttons are pressed.
@@ -1128,13 +1128,13 @@ class GraphPlot(MatplotPanel):
1128
1128
  MatplotPanel.on_pick(self, evt) # [art_picked]
1129
1129
 
1130
1130
  self.canvas.draw_idle()
1131
-
1131
+
1132
1132
  def on_picker_lock(self, evt):
1133
1133
  self.__isPicked = True
1134
-
1134
+
1135
1135
  def on_picker_unlock(self, evt):
1136
1136
  self.__isPicked = False
1137
-
1137
+
1138
1138
  def OnImagePicked(self, evt): #<matplotlib.backend_bases.PickEvent>
1139
1139
  x = evt.mouseevent.xdata
1140
1140
  y = evt.mouseevent.ydata
@@ -1142,13 +1142,13 @@ class GraphPlot(MatplotPanel):
1142
1142
  x, y = self.frame.xyfrompixel(nx, ny)
1143
1143
  evt.ind = (ny, nx)
1144
1144
  self.selector = (x, y)
1145
-
1145
+
1146
1146
  def _inaxes(self, evt):
1147
1147
  try:
1148
1148
  return evt.inaxes is not self.axes #<matplotlib.backend_bases.MouseEvent>
1149
1149
  except AttributeError:
1150
1150
  return None #<wx._core.KeyEvent>
1151
-
1151
+
1152
1152
  ## --------------------------------
1153
1153
  ## Pan/Zoom actions (override)
1154
1154
  ## --------------------------------
@@ -1156,7 +1156,7 @@ class GraphPlot(MatplotPanel):
1156
1156
  ## spline36, hanning, hamming, hermite, kaiser, quadric,
1157
1157
  ## catrom, gaussian, bessel, mitchell, sinc, lanczos, or none
1158
1158
  interpolation_mode = 'bilinear'
1159
-
1159
+
1160
1160
  def OnDraw(self, evt):
1161
1161
  """Called before canvas.draw (overridden)."""
1162
1162
  if not self.interpolation_mode:
@@ -1171,33 +1171,33 @@ class GraphPlot(MatplotPanel):
1171
1171
 
1172
1172
  elif frame.get_interpolation() != 'nearest' and dots > 1:
1173
1173
  frame.set_interpolation('nearest')
1174
-
1174
+
1175
1175
  def OnMotion(self, evt):
1176
1176
  """Called when mouse moves in axes (overridden)."""
1177
1177
  if self.selector.shape[1] < 2:
1178
1178
  self.trace_point(evt.xdata, evt.ydata)
1179
-
1179
+
1180
1180
  def OnPageDown(self, evt):
1181
1181
  """Next page."""
1182
1182
  i = self.__index
1183
1183
  if i is not None and i < len(self)-1:
1184
1184
  self.select(i + 1)
1185
-
1185
+
1186
1186
  def OnPageUp(self, evt):
1187
1187
  """Previous page."""
1188
1188
  i = self.__index
1189
1189
  if i is not None and i > 0:
1190
1190
  self.select(i - 1)
1191
-
1191
+
1192
1192
  def OnHomePosition(self, evt):
1193
1193
  self.fit_to_axes()
1194
-
1194
+
1195
1195
  def OnEscapeSelection(self, evt):
1196
1196
  xs, ys = self.selector
1197
1197
  del self.selector
1198
1198
  if len(xs) > 1:
1199
1199
  self.handler('line_removed', self.frame)
1200
-
1200
+
1201
1201
  def OnXAxisPanZoom(self, evt, c=None):
1202
1202
  org = self.p_event
1203
1203
  M = np.exp(-(evt.x - org.x)/100)
@@ -1207,7 +1207,7 @@ class GraphPlot(MatplotPanel):
1207
1207
  self.ylim = self.zoomlim(self.ylim, M)
1208
1208
  org.x, org.y = evt.x, evt.y
1209
1209
  self.draw()
1210
-
1210
+
1211
1211
  def OnYAxisPanZoom(self, evt, c=None):
1212
1212
  org = self.p_event
1213
1213
  M = np.exp(-(evt.y - org.y)/100)
@@ -1217,11 +1217,11 @@ class GraphPlot(MatplotPanel):
1217
1217
  self.ylim = self.zoomlim(self.ylim, M, c)
1218
1218
  org.x, org.y = evt.x, evt.y
1219
1219
  self.draw()
1220
-
1220
+
1221
1221
  ## --------------------------------
1222
1222
  ## Selector interface
1223
1223
  ## --------------------------------
1224
-
1224
+
1225
1225
  def calc_point(self, x, y, centred=True, inaxes=False):
1226
1226
  """Computes the nearest pixelated point from a point (x, y).
1227
1227
  If centred, correct the points to the center of the nearest pixel.
@@ -1249,7 +1249,7 @@ class GraphPlot(MatplotPanel):
1249
1249
  x = l + nx * ux
1250
1250
  y = t - ny * uy
1251
1251
  return (x, y)
1252
-
1252
+
1253
1253
  def calc_shiftpoint(self, xo, yo, x, y, centred=True):
1254
1254
  """Restrict point (x, y) from (xo, yo) in pi/8 step angles.
1255
1255
  If centred, correct the point to the center of the nearest pixel.
@@ -1262,16 +1262,16 @@ class GraphPlot(MatplotPanel):
1262
1262
  x = xo + L * np.cos(aa[k] - pi/8)
1263
1263
  y = yo + L * np.sin(aa[k] - pi/8)
1264
1264
  return self.calc_point(x, y, centred)
1265
-
1265
+
1266
1266
  def OnSelectorAppend(self, evt):
1267
1267
  xs, ys = self.selector
1268
1268
  x, y = self.calc_point(evt.xdata, evt.ydata)
1269
1269
  self.selector = np.append(xs, x), np.append(ys, y)
1270
1270
  self.handler('line_drawn', self.frame)
1271
-
1271
+
1272
1272
  def OnDragLock(self, evt):
1273
1273
  pass
1274
-
1274
+
1275
1275
  def OnDragBegin(self, evt):
1276
1276
  if not self.frame or self._inaxes(evt):
1277
1277
  self.handler('quit', evt)
@@ -1279,7 +1279,7 @@ class GraphPlot(MatplotPanel):
1279
1279
  org = self.p_event # the last pressed
1280
1280
  self.__lastpoint = self.calc_point(org.xdata, org.ydata)
1281
1281
  self.__orgpoints = self.selector
1282
-
1282
+
1283
1283
  def OnDragMove(self, evt, shift=False):
1284
1284
  x, y = self.calc_point(evt.xdata, evt.ydata)
1285
1285
  xo, yo = self.__lastpoint
@@ -1287,10 +1287,10 @@ class GraphPlot(MatplotPanel):
1287
1287
  x, y = self.calc_shiftpoint(xo, yo, x, y)
1288
1288
  self.selector = np.append(xo, x), np.append(yo, y)
1289
1289
  self.handler('line_draw', self.frame)
1290
-
1290
+
1291
1291
  def OnDragShiftMove(self, evt):
1292
1292
  self.OnDragMove(evt, shift=True)
1293
-
1293
+
1294
1294
  def OnDragEscape(self, evt):
1295
1295
  self.selector = self.__orgpoints
1296
1296
  self.handler('line_draw', self.frame)
@@ -1301,11 +1301,11 @@ class GraphPlot(MatplotPanel):
1301
1301
  if x == xo and y == yo:
1302
1302
  self.selector = ([x], [y])
1303
1303
  self.handler('line_drawn', self.frame)
1304
-
1304
+
1305
1305
  ## --------------------------------
1306
1306
  ## Selector + Line interface
1307
1307
  ## --------------------------------
1308
-
1308
+
1309
1309
  def OnLineSelected(self, evt):
1310
1310
  k = evt.ind[0]
1311
1311
  x = evt.mouseevent.xdata
@@ -1313,10 +1313,10 @@ class GraphPlot(MatplotPanel):
1313
1313
  xs, ys = evt.artist.get_data(orig=0)
1314
1314
  dots = np.hypot(x-xs[k], y-ys[k]) * self.ddpu[0]
1315
1315
  self.__linesel = k if dots < 8 else None
1316
-
1316
+
1317
1317
  def OnLineDeselected(self, evt): #<matplotlib.backend_bases.PickEvent>
1318
1318
  self.__linesel = None
1319
-
1319
+
1320
1320
  def OnLineDragBegin(self, evt):
1321
1321
  if not self.frame or self._inaxes(evt):
1322
1322
  self.handler('quit', evt)
@@ -1324,7 +1324,7 @@ class GraphPlot(MatplotPanel):
1324
1324
  org = self.p_event # the last pressed
1325
1325
  self.__lastpoint = self.calc_point(org.xdata, org.ydata)
1326
1326
  self.__orgpoints = self.selector
1327
-
1327
+
1328
1328
  def OnLineDragMove(self, evt, shift=False):
1329
1329
  x, y = self.calc_point(evt.xdata, evt.ydata)
1330
1330
  xc, yc = self.__lastpoint
@@ -1344,23 +1344,23 @@ class GraphPlot(MatplotPanel):
1344
1344
  ys = yo + (y - yc)
1345
1345
  self.selector = (xs, ys)
1346
1346
  self.handler('line_move', self.frame)
1347
-
1347
+
1348
1348
  def OnLineDragShiftMove(self, evt):
1349
1349
  self.OnLineDragMove(evt, shift=True)
1350
-
1350
+
1351
1351
  def OnLineDragEscape(self, evt):
1352
1352
  self.selector = self.__orgpoints
1353
1353
  if self.__linesel:
1354
1354
  self.handler('line_drawn', self.frame)
1355
1355
  else:
1356
1356
  self.handler('line_moved', self.frame)
1357
-
1357
+
1358
1358
  def OnLineDragEnd(self, evt):
1359
1359
  if self.__linesel:
1360
1360
  self.handler('line_drawn', self.frame)
1361
1361
  else:
1362
1362
  self.handler('line_moved', self.frame)
1363
-
1363
+
1364
1364
  def OnLineShift(self, evt):
1365
1365
  if self.selector.size and self.frame:
1366
1366
  ux, uy = self.frame.xy_unit
@@ -1372,23 +1372,23 @@ class GraphPlot(MatplotPanel):
1372
1372
  }
1373
1373
  self.selector += np.resize(du[evt.key], (2,1))
1374
1374
  self.handler('line_move', self.frame)
1375
-
1375
+
1376
1376
  def OnLineShiftEnd(self, evt):
1377
1377
  self.handler('line_moved', self.frame)
1378
-
1378
+
1379
1379
  ## --------------------------------
1380
1380
  ## Marker interface
1381
1381
  ## --------------------------------
1382
-
1382
+
1383
1383
  #: Limit number of markers to display 最大(表示)数を制限する
1384
1384
  maxnum_markers = 1000
1385
-
1385
+
1386
1386
  @property
1387
1387
  def markers(self):
1388
1388
  """Marked points data array [[x],[y]]."""
1389
1389
  xm, ym = self.marked.get_data(orig=0)
1390
1390
  return np.array((xm, ym))
1391
-
1391
+
1392
1392
  @markers.setter
1393
1393
  def markers(self, v):
1394
1394
  x, y = v
@@ -1401,7 +1401,7 @@ class GraphPlot(MatplotPanel):
1401
1401
  self.__marksel = []
1402
1402
  self.update_art_of_mark()
1403
1403
  self.handler('mark_drawn', self.frame)
1404
-
1404
+
1405
1405
  @markers.deleter
1406
1406
  def markers(self):
1407
1407
  if self.markers.size:
@@ -1409,12 +1409,12 @@ class GraphPlot(MatplotPanel):
1409
1409
  self.__marksel = []
1410
1410
  self.update_art_of_mark()
1411
1411
  self.handler('mark_removed', self.frame)
1412
-
1412
+
1413
1413
  def get_current_mark(self):
1414
1414
  """Currently selected mark."""
1415
1415
  xm, ym = self.marked.get_data(orig=0)
1416
1416
  return np.take((xm, ym), self.__marksel, axis=1)
1417
-
1417
+
1418
1418
  def set_current_mark(self, x, y):
1419
1419
  xm, ym = self.marked.get_data(orig=0)
1420
1420
  j = self.__marksel
@@ -1431,7 +1431,7 @@ class GraphPlot(MatplotPanel):
1431
1431
  self.marked.set_visible(1)
1432
1432
  self.update_art_of_mark()
1433
1433
  self.selector = (x, y)
1434
-
1434
+
1435
1435
  def del_current_mark(self):
1436
1436
  j = self.__marksel
1437
1437
  if j:
@@ -1442,7 +1442,7 @@ class GraphPlot(MatplotPanel):
1442
1442
  n = len(xm)
1443
1443
  self.__marksel = [j[-1] % n] if n > 0 else []
1444
1444
  self.update_art_of_mark()
1445
-
1445
+
1446
1446
  def update_art_of_mark(self, *args):
1447
1447
  if args:
1448
1448
  for k, x, y in zip(*args):
@@ -1467,19 +1467,19 @@ class GraphPlot(MatplotPanel):
1467
1467
  )
1468
1468
  self.trace_point(*self.get_current_mark(), type=MARK)
1469
1469
  self.draw(self.marked)
1470
-
1470
+
1471
1471
  def OnMarkAppend(self, evt):
1472
1472
  xs, ys = self.selector
1473
1473
  if not self.__marksel and len(xs) > 0:
1474
1474
  self.set_current_mark(xs, ys)
1475
1475
  self.handler('mark_drawn', self.frame)
1476
1476
  self.update_art_of_mark()
1477
-
1477
+
1478
1478
  def OnMarkRemove(self, evt):
1479
1479
  if self.__marksel:
1480
1480
  self.del_current_mark()
1481
1481
  self.handler('mark_removed', self.frame)
1482
-
1482
+
1483
1483
  def OnMarkSelected(self, evt): #<matplotlib.backend_bases.PickEvent>
1484
1484
  k = evt.ind[0]
1485
1485
  if evt.mouseevent.key == 'shift': # 多重マーカー選択
@@ -1491,29 +1491,29 @@ class GraphPlot(MatplotPanel):
1491
1491
  self.selector = self.get_current_mark()
1492
1492
  if self.selector.shape[1] > 1:
1493
1493
  self.handler('line_drawn', self.frame) # 多重マーカー選択時
1494
-
1494
+
1495
1495
  def OnMarkDeselected(self, evt): #<matplotlib.backend_bases.PickEvent>
1496
1496
  self.__marksel = []
1497
1497
  self.update_art_of_mark()
1498
-
1498
+
1499
1499
  def OnMarkDragBegin(self, evt):
1500
1500
  if not self.frame or self._inaxes(evt):
1501
1501
  self.handler('quit', evt)
1502
1502
  return
1503
1503
  self.__orgpoints = self.get_current_mark()
1504
-
1504
+
1505
1505
  def OnMarkDragMove(self, evt):
1506
1506
  x, y = self.calc_point(evt.xdata, evt.ydata)
1507
1507
  self.set_current_mark(x, y)
1508
1508
  self.handler('mark_draw', self.frame)
1509
-
1509
+
1510
1510
  def OnMarkDragEscape(self, evt):
1511
1511
  self.set_current_mark(*self.__orgpoints)
1512
1512
  self.handler('mark_drawn', self.frame)
1513
-
1513
+
1514
1514
  def OnMarkDragEnd(self, evt):
1515
1515
  self.handler('mark_drawn', self.frame)
1516
-
1516
+
1517
1517
  def OnMarkShift(self, evt):
1518
1518
  j = self.__marksel
1519
1519
  if j and self.frame:
@@ -1527,10 +1527,10 @@ class GraphPlot(MatplotPanel):
1527
1527
  p = self.get_current_mark() + np.resize(du[evt.key], (2,1))
1528
1528
  self.set_current_mark(*p)
1529
1529
  self.handler('mark_draw', self.frame)
1530
-
1530
+
1531
1531
  def OnMarkShiftEnd(self, evt):
1532
1532
  self.handler('mark_drawn', self.frame)
1533
-
1533
+
1534
1534
  def next_mark(self, j):
1535
1535
  self.__marksel = [j]
1536
1536
  xs, ys = self.get_current_mark()
@@ -1539,7 +1539,7 @@ class GraphPlot(MatplotPanel):
1539
1539
  self.selector = (xs, ys)
1540
1540
  self.trace_point(xs, ys, type=MARK)
1541
1541
  self.draw()
1542
-
1542
+
1543
1543
  def OnMarkSkipNext(self, evt):
1544
1544
  n = self.markers.shape[1]
1545
1545
  j = self.__marksel
@@ -1547,7 +1547,7 @@ class GraphPlot(MatplotPanel):
1547
1547
  self.next_mark((j[-1]+1) % n)
1548
1548
  elif n:
1549
1549
  self.next_mark(0)
1550
-
1550
+
1551
1551
  def OnMarkSkipPrevious(self, evt):
1552
1552
  n = self.markers.shape[1]
1553
1553
  j = self.__marksel
@@ -1555,11 +1555,11 @@ class GraphPlot(MatplotPanel):
1555
1555
  self.next_mark((j[-1]-1) % n)
1556
1556
  elif n:
1557
1557
  self.next_mark(-1)
1558
-
1558
+
1559
1559
  ## --------------------------------
1560
1560
  ## Region interface
1561
1561
  ## --------------------------------
1562
-
1562
+
1563
1563
  @property
1564
1564
  def region(self):
1565
1565
  """Cropped rectangle points data array [l,r],[b,t]."""
@@ -1569,26 +1569,26 @@ class GraphPlot(MatplotPanel):
1569
1569
  yo, y = min(y), max(y) #= y[[0, 2]]
1570
1570
  return np.array(((xo, x), (yo, y)))
1571
1571
  return np.resize(0., (2,0))
1572
-
1572
+
1573
1573
  @region.setter
1574
1574
  def region(self, v):
1575
1575
  x, y = v
1576
1576
  if len(x) > 1:
1577
1577
  self.set_current_rect(x, y)
1578
1578
  self.handler('region_drawn', self.frame)
1579
-
1579
+
1580
1580
  @region.deleter
1581
1581
  def region(self):
1582
1582
  if self.region.size:
1583
1583
  self.del_current_rect()
1584
1584
  self.handler('region_removed', self.frame)
1585
-
1585
+
1586
1586
  def get_current_rect(self):
1587
1587
  """Currently selected region."""
1588
1588
  if self.__rectsel:
1589
1589
  x, y = self.rected.get_data(orig=0)
1590
1590
  return np.array((x, y))
1591
-
1591
+
1592
1592
  def set_current_rect(self, x, y):
1593
1593
  if len(x) == 2:
1594
1594
  (xa,xb), (ya,yb) = x, y
@@ -1610,13 +1610,13 @@ class GraphPlot(MatplotPanel):
1610
1610
  self.rected.set_data(x, y)
1611
1611
  self.rected.set_visible(1)
1612
1612
  self.update_art_of_region()
1613
-
1613
+
1614
1614
  def del_current_rect(self):
1615
1615
  self.__rectsel = []
1616
1616
  self.rected.set_data([], [])
1617
1617
  self.rected.set_visible(0)
1618
1618
  self.update_art_of_region()
1619
-
1619
+
1620
1620
  def update_art_of_region(self, *args):
1621
1621
  if args:
1622
1622
  art = self.__rectarts # art の再描画処理をして終了
@@ -1637,7 +1637,7 @@ class GraphPlot(MatplotPanel):
1637
1637
  )
1638
1638
  self.trace_point(x, y, type=REGION)
1639
1639
  self.draw(self.rected)
1640
-
1640
+
1641
1641
  def OnRegionAppend(self, evt):
1642
1642
  xs, ys = self.selector
1643
1643
  if len(xs) > 0 and self.frame:
@@ -1647,13 +1647,13 @@ class GraphPlot(MatplotPanel):
1647
1647
  self.set_current_rect(xs, ys)
1648
1648
  self.update_art_of_region()
1649
1649
  self.handler('region_drawn', self.frame)
1650
-
1650
+
1651
1651
  def OnRegionRemove(self, evt):
1652
1652
  if self.__rectsel:
1653
1653
  self.del_current_rect()
1654
1654
  self.handler('region_removed', self.frame)
1655
1655
  self.set_wxcursor(wx.CURSOR_ARROW)
1656
-
1656
+
1657
1657
  def OnRegionSelected(self, evt): #<matplotlib.backend_bases.PickEvent>
1658
1658
  k = evt.ind[0]
1659
1659
  x = evt.mouseevent.xdata
@@ -1662,12 +1662,12 @@ class GraphPlot(MatplotPanel):
1662
1662
  dots = np.hypot(x-xs[k], y-ys[k]) * self.ddpu[0]
1663
1663
  self.__rectsel = [k] if dots < 8 else [0,1,2,3,4] # リージョンの全選択
1664
1664
  self.update_art_of_region()
1665
-
1665
+
1666
1666
  def OnRegionDeselected(self, evt): #<matplotlib.backend_bases.PickEvent>
1667
1667
  self.__rectsel = []
1668
1668
  self.update_art_of_region()
1669
1669
  self.set_wxcursor(wx.CURSOR_ARROW)
1670
-
1670
+
1671
1671
  def OnRegionDragBegin(self, evt):
1672
1672
  if not self.frame or self._inaxes(evt):
1673
1673
  self.handler('quit', evt)
@@ -1678,7 +1678,7 @@ class GraphPlot(MatplotPanel):
1678
1678
  x, y = self.__lastpoint
1679
1679
  self.set_current_rect((x, x), (y, y)) # start new region
1680
1680
  self.__orgpoints = self.get_current_rect()
1681
-
1681
+
1682
1682
  def OnRegionDragMove(self, evt, shift=False, meta=False):
1683
1683
  x, y = self.calc_point(evt.xdata, evt.ydata, centred=False)
1684
1684
  xs, ys = self.get_current_rect()
@@ -1703,21 +1703,21 @@ class GraphPlot(MatplotPanel):
1703
1703
  ys = yo + (y - yc)
1704
1704
  self.set_current_rect(xs, ys)
1705
1705
  self.handler('region_draw', self.frame)
1706
-
1706
+
1707
1707
  def OnRegionDragShiftMove(self, evt):
1708
1708
  self.OnRegionDragMove(evt, shift=True)
1709
-
1709
+
1710
1710
  def OnRegionDragMetaMove(self, evt):
1711
1711
  self.OnRegionDragMove(evt, meta=True)
1712
-
1712
+
1713
1713
  def OnRegionDragEscape(self, evt):
1714
1714
  self.set_current_rect(*self.__orgpoints)
1715
1715
  self.handler('region_drawn', self.frame)
1716
-
1716
+
1717
1717
  def OnRegionDragEnd(self, evt):
1718
1718
  ## self.__rectsel = [0,1,2,3,4] # リージョンの全選択
1719
1719
  self.handler('region_drawn', self.frame)
1720
-
1720
+
1721
1721
  def OnRegionShift(self, evt):
1722
1722
  j = self.__rectsel
1723
1723
  if j and self.frame:
@@ -1739,10 +1739,10 @@ class GraphPlot(MatplotPanel):
1739
1739
  p += dp
1740
1740
  self.set_current_rect(*p.T)
1741
1741
  self.handler('region_draw', self.frame)
1742
-
1742
+
1743
1743
  def OnRegionShiftEnd(self, evt):
1744
1744
  self.handler('region_drawn', self.frame)
1745
-
1745
+
1746
1746
  def OnRegionMotion(self, evt):
1747
1747
  x, y = evt.xdata, evt.ydata
1748
1748
  if self.region.size: