pygmi 2.2.7__zip

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.
Files changed (106) hide show
  1. pygmi-2.2.7/LICENSE.txt +623 -0
  2. pygmi-2.2.7/MANIFEST.in +7 -0
  3. pygmi-2.2.7/PKG-INFO +47 -0
  4. pygmi-2.2.7/README.md +55 -0
  5. pygmi-2.2.7/README.rst +20 -0
  6. pygmi-2.2.7/log.txt +242 -0
  7. pygmi-2.2.7/pygmi/__init__.py +22 -0
  8. pygmi-2.2.7/pygmi/clust/__init__.py +4 -0
  9. pygmi-2.2.7/pygmi/clust/crisp_clust.py +708 -0
  10. pygmi-2.2.7/pygmi/clust/datatypes.py +65 -0
  11. pygmi-2.2.7/pygmi/clust/fuzzy_clust.py +906 -0
  12. pygmi-2.2.7/pygmi/clust/graphs.py +421 -0
  13. pygmi-2.2.7/pygmi/clust/graphtool.py +667 -0
  14. pygmi-2.2.7/pygmi/clust/menu.py +139 -0
  15. pygmi-2.2.7/pygmi/clust/var_ratio.py +92 -0
  16. pygmi-2.2.7/pygmi/clust/xie_beni.py +93 -0
  17. pygmi-2.2.7/pygmi/helpdocs/linepointer.png +0 -0
  18. pygmi-2.2.7/pygmi/helpdocs/pygmi.main.html +31 -0
  19. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.ddisp.html +15 -0
  20. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.exportkmz.html +13 -0
  21. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.importpicture.html +16 -0
  22. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.layer.html +17 -0
  23. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.mext.html +44 -0
  24. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.misc.rangedcopy.html +16 -0
  25. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.param.html +37 -0
  26. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.prof.html +32 -0
  27. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.pview.html +26 -0
  28. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.gradients.html +14 -0
  29. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.tilt.html +14 -0
  30. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.visibility.html +14 -0
  31. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datagrid.html +13 -0
  32. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datamerge.html +11 -0
  33. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datareproj.html +11 -0
  34. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.rtp.html +14 -0
  35. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.ginterp.html +31 -0
  36. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.igrf.html +20 -0
  37. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.normalisation.html +14 -0
  38. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.smooth.html +22 -0
  39. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.tiltdepth.html +20 -0
  40. pygmi-2.2.7/pygmi/images/Help.png +0 -0
  41. pygmi-2.2.7/pygmi/images/bringtofront.png +0 -0
  42. pygmi-2.2.7/pygmi/images/cgs2.emf +0 -0
  43. pygmi-2.2.7/pygmi/images/delete.png +0 -0
  44. pygmi-2.2.7/pygmi/images/linepointer.png +0 -0
  45. pygmi-2.2.7/pygmi/images/logo256.ico +0 -0
  46. pygmi-2.2.7/pygmi/images/logo256.png +0 -0
  47. pygmi-2.2.7/pygmi/images/pointer.png +0 -0
  48. pygmi-2.2.7/pygmi/images/pygmi.png +0 -0
  49. pygmi-2.2.7/pygmi/images/sendtoback.png +0 -0
  50. pygmi-2.2.7/pygmi/main.py +1037 -0
  51. pygmi-2.2.7/pygmi/menu_default.py +327 -0
  52. pygmi-2.2.7/pygmi/misc.py +147 -0
  53. pygmi-2.2.7/pygmi/pfmod/__init__.py +6 -0
  54. pygmi-2.2.7/pygmi/pfmod/cubes.py +1488 -0
  55. pygmi-2.2.7/pygmi/pfmod/datatypes.py +292 -0
  56. pygmi-2.2.7/pygmi/pfmod/grvmag3d.py +1265 -0
  57. pygmi-2.2.7/pygmi/pfmod/iodefs.py +1001 -0
  58. pygmi-2.2.7/pygmi/pfmod/menu.py +107 -0
  59. pygmi-2.2.7/pygmi/pfmod/misc.py +301 -0
  60. pygmi-2.2.7/pygmi/pfmod/pfmod.py +248 -0
  61. pygmi-2.2.7/pygmi/pfmod/tab_ddisp.py +425 -0
  62. pygmi-2.2.7/pygmi/pfmod/tab_layer.py +490 -0
  63. pygmi-2.2.7/pygmi/pfmod/tab_mext.py +544 -0
  64. pygmi-2.2.7/pygmi/pfmod/tab_param.py +548 -0
  65. pygmi-2.2.7/pygmi/pfmod/tab_prof.py +946 -0
  66. pygmi-2.2.7/pygmi/pfmod/tab_pview.py +740 -0
  67. pygmi-2.2.7/pygmi/raster/IGRF11.COF +1635 -0
  68. pygmi-2.2.7/pygmi/raster/__init__.py +14 -0
  69. pygmi-2.2.7/pygmi/raster/cooper.py +718 -0
  70. pygmi-2.2.7/pygmi/raster/dataprep.py +1640 -0
  71. pygmi-2.2.7/pygmi/raster/datatypes.py +123 -0
  72. pygmi-2.2.7/pygmi/raster/equation_editor.py +256 -0
  73. pygmi-2.2.7/pygmi/raster/ginterp.py +1901 -0
  74. pygmi-2.2.7/pygmi/raster/graphs.py +531 -0
  75. pygmi-2.2.7/pygmi/raster/igrf.py +860 -0
  76. pygmi-2.2.7/pygmi/raster/iodefs.py +813 -0
  77. pygmi-2.2.7/pygmi/raster/menu.py +307 -0
  78. pygmi-2.2.7/pygmi/raster/normalisation.py +187 -0
  79. pygmi-2.2.7/pygmi/raster/show_table.py +245 -0
  80. pygmi-2.2.7/pygmi/raster/smooth.py +406 -0
  81. pygmi-2.2.7/pygmi/raster/tiltdepth.py +590 -0
  82. pygmi-2.2.7/pygmi/seis/__init__.py +0 -0
  83. pygmi-2.2.7/pygmi/seis/beachball.py +751 -0
  84. pygmi-2.2.7/pygmi/seis/datatypes.py +605 -0
  85. pygmi-2.2.7/pygmi/seis/del_rec.py +410 -0
  86. pygmi-2.2.7/pygmi/seis/iodefs.py +1261 -0
  87. pygmi-2.2.7/pygmi/seis/menu.py +136 -0
  88. pygmi-2.2.7/pygmi/seis/scan_imp.py +795 -0
  89. pygmi-2.2.7/pygmi/test/__init__.py +6 -0
  90. pygmi-2.2.7/pygmi/test/pfmod.py +212 -0
  91. pygmi-2.2.7/pygmi/test/tests.py +39 -0
  92. pygmi-2.2.7/pygmi/vector/__init__.py +7 -0
  93. pygmi-2.2.7/pygmi/vector/datatypes.py +74 -0
  94. pygmi-2.2.7/pygmi/vector/graphs.py +443 -0
  95. pygmi-2.2.7/pygmi/vector/iodefs.py +345 -0
  96. pygmi-2.2.7/pygmi/vector/menu.py +127 -0
  97. pygmi-2.2.7/pygmi.egg-info/PKG-INFO +47 -0
  98. pygmi-2.2.7/pygmi.egg-info/SOURCES.txt +105 -0
  99. pygmi-2.2.7/pygmi.egg-info/dependency_links.txt +1 -0
  100. pygmi-2.2.7/pygmi.egg-info/entry_points.txt +3 -0
  101. pygmi-2.2.7/pygmi.egg-info/not-zip-safe +1 -0
  102. pygmi-2.2.7/pygmi.egg-info/requires.txt +7 -0
  103. pygmi-2.2.7/pygmi.egg-info/top_level.txt +1 -0
  104. pygmi-2.2.7/quickstart.py +35 -0
  105. pygmi-2.2.7/setup.cfg +8 -0
  106. pygmi-2.2.7/setup.py +80 -0
@@ -0,0 +1,667 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Name: graph_tool.py (part of PyGMI)
3
+ #
4
+ # Author: Patrick Cole
5
+ # E-Mail: pcole@geoscience.org.za
6
+ #
7
+ # Copyright: (c) 2013 Council for Geoscience
8
+ # Licence: GPL-3.0
9
+ #
10
+ # This file is part of PyGMI
11
+ #
12
+ # PyGMI is free software: you can redistribute it and/or modify
13
+ # it under the terms of the GNU General Public License as published by
14
+ # the Free Software Foundation, either version 3 of the License, or
15
+ # (at your option) any later version.
16
+ #
17
+ # PyGMI is distributed in the hope that it will be useful,
18
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ # GNU General Public License for more details.
21
+ #
22
+ # You should have received a copy of the GNU General Public License
23
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
24
+ # -----------------------------------------------------------------------------
25
+ """
26
+ Graph tool is a multi-function graphing tool for use with cluster analysis
27
+ """
28
+
29
+ import numpy as np
30
+ from PyQt4 import QtGui, QtCore
31
+ from matplotlib.figure import Figure
32
+ import matplotlib.pylab as plt
33
+ from matplotlib.path import Path
34
+ from matplotlib.backends.backend_qt4agg import FigureCanvas
35
+
36
+
37
+ class GraphHist(FigureCanvas):
38
+ """
39
+ Plots several lines in distinct colors.
40
+
41
+ Parameters
42
+ ----------
43
+ parent : parent
44
+ reference to the parent routine.
45
+ """
46
+ def __init__(self, parent=None):
47
+ self.figure = Figure()
48
+
49
+ FigureCanvas.__init__(self, self.figure)
50
+ self.setParent(parent)
51
+
52
+ self.nullfmt = plt.NullFormatter()
53
+ self.pntxy = None
54
+ self.polyi = None
55
+ self.axhistx = None
56
+ self.axhisty = None
57
+ self.axscatter = None
58
+ self.histx = None
59
+ self.histy = None
60
+ self.xcoord = None
61
+ self.ycoord = None
62
+ self.data = []
63
+ self.cindx = [0, 1, 0]
64
+ self.cdata = []
65
+ self.csp = None
66
+
67
+ def get_hist(self, bins):
68
+ """ Routine to get the scattergram with histogram overlay """
69
+ xyhist = np.zeros((bins + 1, bins + 1))
70
+ xxx = self.xcoord.compressed()
71
+ yyy = self.ycoord.compressed()
72
+
73
+ xyhist = np.histogram2d(xxx, yyy, bins + 1)
74
+
75
+ xymahist = np.ma.masked_equal(xyhist[0], 0)
76
+ return xymahist
77
+
78
+ def get_clust_scat(self, bins, dattmp, ctmp):
79
+ """ Routine to get the scattergram with cluster overlay """
80
+ clust = np.ma.array(dattmp[ctmp[2] - 1].data.flatten())
81
+ clust.mask = self.xcoord.mask
82
+ clust = clust.compressed()
83
+ xxx = self.xcoord.compressed()
84
+ yyy = self.ycoord.compressed()
85
+ xyhist = np.zeros((bins + 1, bins + 1))
86
+
87
+ xyhist[xxx, yyy] = (clust + 1)
88
+
89
+ xymahist = np.ma.masked_equal(xyhist, 0)
90
+ return xymahist
91
+
92
+ def init_graph(self):
93
+ """ Initialize the Graph """
94
+ # definitions for the axes
95
+ self.figure.clf()
96
+
97
+ left, width = 0.1, 0.65
98
+ bottom, height = 0.1, 0.65
99
+ bottom_h = bottom + height + 0.02
100
+ left_h = left + width + 0.02
101
+
102
+ rect_scatter = [left, bottom, width, height]
103
+ rect_histx = [left, bottom_h, width, 0.2]
104
+ rect_histy = [left_h, bottom, 0.2, height]
105
+
106
+ self.axscatter = self.figure.add_axes(rect_scatter, label='s')
107
+ self.axhistx = self.figure.add_axes(rect_histx, label='x')
108
+ self.axhisty = self.figure.add_axes(rect_histy, label='y')
109
+
110
+ # Setup the coordinates
111
+ self.setup_coords()
112
+
113
+ # setup 1d histograms
114
+ self.setup_hist()
115
+
116
+ # Compressed eliminates the masked values so that hist
117
+ xymahist = self.get_hist(50)
118
+
119
+ self.axscatter.get_xaxis().set_visible(False)
120
+ self.axscatter.get_yaxis().set_visible(False)
121
+
122
+ self.csp = self.axscatter.imshow(xymahist.T, interpolation='nearest',
123
+ cmap=plt.cm.jet, aspect='auto')
124
+
125
+ self.figure.canvas.draw()
126
+
127
+ def polyint(self):
128
+ """ Polygon Interactor routine """
129
+ pntxy = np.transpose([self.xcoord, self.ycoord])
130
+ self.polyi = PolygonInteractor(self.axscatter, pntxy)
131
+ self.polyi.ishist = True
132
+
133
+ def setup_coords(self):
134
+ """ Routine to setup the coordinates for the scattergram """
135
+ self.xcoord = self.data[self.cindx[0]].data.flatten()
136
+ self.ycoord = self.data[self.cindx[1]].data.flatten()
137
+ self.xcoord -= self.xcoord.min()
138
+ self.ycoord -= self.ycoord.min()
139
+ xptp = self.xcoord.ptp()
140
+ yptp = self.ycoord.ptp()
141
+ xstep = xptp / 50
142
+ ystep = yptp / 50
143
+ self.xcoord /= xstep
144
+ self.ycoord /= ystep
145
+ self.xcoord = self.xcoord.astype(int)
146
+ self.ycoord = self.ycoord.astype(int)
147
+
148
+ def setup_hist(self):
149
+ """ Routine to setup the 1d histograms """
150
+ self.axhistx.xaxis.set_major_formatter(self.nullfmt)
151
+ self.axhisty.yaxis.set_major_formatter(self.nullfmt)
152
+ self.axhistx.yaxis.set_major_formatter(self.nullfmt)
153
+ self.axhisty.xaxis.set_major_formatter(self.nullfmt)
154
+ xrng = [self.xcoord.min(), self.xcoord.max()]
155
+ yrng = [self.ycoord.min(), self.ycoord.max()]
156
+ self.histx = self.axhistx.hist(self.xcoord.compressed(), 50)
157
+ self.histy = self.axhisty.hist(self.ycoord.compressed(), 50,
158
+ orientation='horizontal')
159
+ self.axhistx.set_xlim(xrng)
160
+ self.axhisty.set_ylim(yrng[::-1])
161
+
162
+ def update_graph(self, clearaxis=False):
163
+ """ Draw Routine """
164
+ if clearaxis is True:
165
+ self.axhistx.cla()
166
+ self.axhisty.cla()
167
+
168
+ self.setup_coords()
169
+ self.polyi.pntxy = np.array([self.xcoord, self.ycoord]).T
170
+ self.setup_hist()
171
+
172
+ if self.cindx[2] > 0:
173
+ xymahist = self.get_clust_scat(50, self.cdata, self.cindx)
174
+ else:
175
+ xymahist = self.get_hist(50)
176
+
177
+ if self.csp is None:
178
+ return
179
+
180
+ self.csp.set_data(xymahist.T)
181
+ self.csp.set_clim(xymahist.min(), xymahist.max())
182
+ self.csp.changed()
183
+ self.figure.canvas.draw()
184
+ self.polyi.draw_callback()
185
+
186
+
187
+ class GraphMap(FigureCanvas):
188
+ """
189
+ Plots several lines in distinct colors.
190
+
191
+ Parameters
192
+ ----------
193
+ parent : parent
194
+ reference to the parent routine.
195
+
196
+ Attributes
197
+ ----------
198
+ parent : parent
199
+ reference to the parent routine
200
+ """
201
+ def __init__(self, parent):
202
+ self.figure = Figure()
203
+
204
+ FigureCanvas.__init__(self, self.figure)
205
+ self.setParent(parent)
206
+
207
+ self.parent = parent
208
+ self.polyi = None
209
+ self.data = []
210
+ self.cdata = []
211
+ self.mindx = [0, 0]
212
+ self.csp = None
213
+ self.subplot = None
214
+
215
+ # def dat_extent(self, dat):
216
+ # """ Gets the extend of the dat variable """
217
+ # left = dat.tlx
218
+ # top = dat.tly
219
+ # right = left + dat.cols*dat.xdim
220
+ # bottom = top - dat.rows*dat.ydim
221
+ # return (left, right, bottom, top)
222
+
223
+ def init_graph(self):
224
+ """ Initialize the Graph """
225
+ mtmp = self.mindx
226
+ dat = self.data[mtmp[0]]
227
+
228
+ self.figure.clf()
229
+ self.subplot = self.figure.add_subplot(111)
230
+ self.subplot.get_xaxis().set_visible(False)
231
+ self.subplot.get_yaxis().set_visible(False)
232
+
233
+ self.csp = self.subplot.imshow(dat.data, cmap=plt.cm.jet)
234
+ self.subplot.figure.colorbar(self.csp)
235
+
236
+ self.figure.canvas.draw()
237
+
238
+ def polyint(self):
239
+ """ Polygon Integrator """
240
+ mtmp = self.mindx
241
+ dat = self.data[mtmp[0]].data
242
+
243
+ xtmp = np.arange(dat.shape[1])
244
+ ytmp = np.arange(dat.shape[0])
245
+ xmesh, ymesh = np.meshgrid(xtmp, ytmp)
246
+ xmesh = np.ma.array(xmesh, dtype=float, mask=dat.mask)
247
+ ymesh = np.ma.array(ymesh, dtype=float, mask=dat.mask)
248
+ xmesh = xmesh.flatten()
249
+ ymesh = ymesh.flatten()
250
+ xmesh = xmesh.filled(np.nan)
251
+ ymesh = ymesh.filled(np.nan)
252
+ pntxy = np.transpose([xmesh, ymesh])
253
+ self.polyi = PolygonInteractor(self.subplot, pntxy)
254
+ self.polyi.ishist = False
255
+
256
+ def update_graph(self):
257
+ """ Draw routine """
258
+ mtmp = self.mindx
259
+ dat = self.data[mtmp[0]]
260
+
261
+ self.figure.clf()
262
+ self.subplot = self.figure.add_subplot(111)
263
+ self.subplot.get_xaxis().set_visible(False)
264
+ self.subplot.get_yaxis().set_visible(False)
265
+
266
+ if mtmp[1] > 0:
267
+ cdat = self.cdata[mtmp[1] - 1].data + 1
268
+ self.csp = self.subplot.imshow(cdat, cmap=plt.cm.jet)
269
+ vals = np.unique(cdat)
270
+ vals = vals.compressed()
271
+ bnds = (vals - 0.5).tolist() + [vals.max() + .5]
272
+ self.subplot.figure.colorbar(self.csp, boundaries=bnds,
273
+ values=vals, ticks=vals)
274
+ else:
275
+ self.csp = self.subplot.imshow(dat.data, cmap=plt.cm.jet)
276
+ self.subplot.figure.colorbar(self.csp)
277
+
278
+ self.figure.canvas.draw()
279
+ self.polyi.draw_callback()
280
+
281
+
282
+ class PolygonInteractor(QtCore.QObject):
283
+ """
284
+ Polygon Interactor
285
+
286
+ Parameters
287
+ ----------
288
+ axtmp : matplotlib axis
289
+ matplotlib axis
290
+ pntxy :
291
+
292
+ """
293
+ showverts = True
294
+ epsilon = 5 # max pixel distance to count as a vertex hit
295
+ polyi_changed = QtCore.pyqtSignal(list)
296
+
297
+ def __init__(self, axtmp, pntxy):
298
+ QtCore.QObject.__init__(self)
299
+ self.ax = axtmp
300
+ self.poly = plt.Polygon([(1, 1)], animated=True)
301
+ self.ax.add_patch(self.poly)
302
+ self.canvas = self.poly.figure.canvas
303
+ self.poly.set_alpha(0.5)
304
+ self.pntxy = pntxy
305
+ self.ishist = True
306
+ self.background = self.canvas.copy_from_bbox(self.ax.bbox)
307
+
308
+ xtmp, ytmp = list(zip(*self.poly.xy))
309
+
310
+ self.line = plt.Line2D(xtmp, ytmp, marker='o', markerfacecolor='r',
311
+ color='y', animated=True)
312
+ self.ax.add_line(self.line)
313
+ # self._update_line(poly)
314
+
315
+ self.poly.add_callback(self.poly_changed)
316
+ self._ind = None # the active vert
317
+
318
+ self.canvas.mpl_connect('button_press_event',
319
+ self.button_press_callback)
320
+ self.canvas.mpl_connect('button_release_event',
321
+ self.button_release_callback)
322
+ self.canvas.mpl_connect('motion_notify_event',
323
+ self.motion_notify_callback)
324
+
325
+ def draw_callback(self):
326
+ """ Draw callback """
327
+ self.background = self.canvas.copy_from_bbox(self.ax.bbox)
328
+ QtGui.QApplication.processEvents()
329
+
330
+ self.canvas.restore_region(self.background)
331
+ self.ax.draw_artist(self.poly)
332
+ self.ax.draw_artist(self.line)
333
+ # self.canvas.blit(self.ax.bbox)
334
+ self.canvas.update()
335
+
336
+ def new_poly(self, npoly):
337
+ """ New Polygon """
338
+ self.poly.set_xy(npoly)
339
+ self.line.set_data(list(zip(*self.poly.xy)))
340
+
341
+ self.canvas.draw()
342
+ self.update_plots()
343
+
344
+ def poly_changed(self, poly):
345
+ """ Changed Polygon """
346
+ # this method is called whenever the polygon object is called
347
+ # only copy the artist props to the line (except visibility)
348
+ vis = self.line.get_visible()
349
+ plt.Artist.update_from(self.line, poly)
350
+ self.line.set_visible(vis) # don't use the poly visibility state
351
+
352
+ def get_ind_under_point(self, event):
353
+ """get the index of vertex under point if within epsilon tolerance"""
354
+
355
+ # display coords
356
+ xytmp = np.asarray(self.poly.xy)
357
+ xyt = self.poly.get_transform().transform(xytmp)
358
+ xtt, ytt = xyt[:, 0], xyt[:, 1]
359
+ dtt = np.sqrt((xtt - event.x) ** 2 + (ytt - event.y) ** 2)
360
+ indseq = np.nonzero(np.equal(dtt, np.amin(dtt)))[0]
361
+ ind = indseq[0]
362
+
363
+ if dtt[ind] >= self.epsilon:
364
+ ind = None
365
+
366
+ return ind
367
+
368
+ def button_press_callback(self, event):
369
+ """whenever a mouse button is pressed"""
370
+ if event.inaxes is None:
371
+ return
372
+ if event.button != 1:
373
+ return
374
+ self._ind = self.get_ind_under_point(event)
375
+
376
+ if self._ind is None:
377
+ xys = self.poly.get_transform().transform(self.poly.xy)
378
+ ptmp = event.x, event.y # display coords
379
+
380
+ if len(xys) == 1:
381
+ self.poly.xy = np.array(
382
+ [(event.xdata, event.ydata)] +
383
+ [(event.xdata, event.ydata)])
384
+ self.line.set_data(list(zip(*self.poly.xy)))
385
+
386
+ self.canvas.restore_region(self.background)
387
+ self.ax.draw_artist(self.poly)
388
+ self.ax.draw_artist(self.line)
389
+ # self.canvas.blit(self.ax.bbox)
390
+ self.canvas.update()
391
+ return
392
+ dmin = -1
393
+ imin = -1
394
+ for i in range(len(xys) - 1):
395
+ s0tmp = xys[i]
396
+ s1tmp = xys[i + 1]
397
+ dtmp = plt.dist_point_to_segment(ptmp, s0tmp, s1tmp)
398
+ if dmin == -1:
399
+ dmin = dtmp
400
+ imin = i
401
+ elif dtmp < dmin:
402
+ dmin = dtmp
403
+ imin = i
404
+ i = imin
405
+ self.poly.xy = np.array(list(self.poly.xy[:i + 1]) +
406
+ [(event.xdata, event.ydata)] +
407
+ list(self.poly.xy[i + 1:]))
408
+ self.line.set_data(list(zip(*self.poly.xy)))
409
+
410
+ self.canvas.restore_region(self.background)
411
+ self.ax.draw_artist(self.poly)
412
+ self.ax.draw_artist(self.line)
413
+ # self.canvas.blit(self.ax.bbox)
414
+ self.canvas.update()
415
+
416
+ def button_release_callback(self, event):
417
+ """Whenever a mouse button is released"""
418
+ if event.button != 1:
419
+ return
420
+ self._ind = None
421
+ self.update_plots()
422
+
423
+ def update_plots(self):
424
+ """ Update Plots """
425
+ polymask = Path(self.poly.xy).contains_points(self.pntxy)
426
+ self.polyi_changed.emit(polymask.tolist())
427
+
428
+ def motion_notify_callback(self, event):
429
+ """on mouse movement"""
430
+ if self._ind is None:
431
+ return
432
+ if event.inaxes is None:
433
+ return
434
+ if event.button != 1:
435
+ return
436
+ xtmp, ytmp = event.xdata, event.ydata
437
+
438
+ self.poly.xy[self._ind] = xtmp, ytmp
439
+ if self._ind == 0:
440
+ self.poly.xy[-1] = xtmp, ytmp
441
+
442
+ self.line.set_data(list(zip(*self.poly.xy)))
443
+
444
+ self.canvas.restore_region(self.background)
445
+ self.ax.draw_artist(self.poly)
446
+ self.ax.draw_artist(self.line)
447
+ # self.canvas.blit(self.ax.bbox)
448
+ self.canvas.update()
449
+
450
+
451
+ class ScatterPlot(QtGui.QDialog):
452
+ """
453
+ Main Graph Tool Routine
454
+
455
+ Parameters
456
+ ----------
457
+ parent : parent
458
+ reference to the parent routine.
459
+
460
+ Attributes
461
+ ----------
462
+ parent : parent
463
+ reference to the parent routine
464
+ indata : dictionary
465
+ dictionary of input datasets
466
+ outdata : dictionary
467
+ dictionary of output datasets
468
+ """
469
+ def __init__(self, parent):
470
+ QtGui.QDialog.__init__(self, parent)
471
+ self.indata = {}
472
+ self.outdata = {}
473
+ self.parent = parent
474
+ self.m1 = 0
475
+ self.c = [0, 1, 0]
476
+ self.m = [0, 0]
477
+ self.dat_tmp = None
478
+
479
+ self.map = GraphMap(self)
480
+ self.hist = GraphHist(self)
481
+
482
+ self.cp_dpoly = QtGui.QPushButton()
483
+ self.cp_combo = QtGui.QComboBox()
484
+ self.cp_combo2 = QtGui.QComboBox()
485
+ self.cp_combo3 = QtGui.QComboBox()
486
+ self.map_dpoly = QtGui.QPushButton()
487
+ self.map_combo = QtGui.QComboBox()
488
+ self.map_combo2 = QtGui.QComboBox()
489
+
490
+ self.setupui()
491
+
492
+ self.hist.cindx = self.c
493
+ self.map.mindx = self.m
494
+
495
+ def setupui(self):
496
+ """ Setup UI """
497
+ grid_main = QtGui.QGridLayout(self)
498
+ group_cp = QtGui.QGroupBox()
499
+ grid_left = QtGui.QGridLayout(group_cp)
500
+ group_map = QtGui.QGroupBox()
501
+ grid_right = QtGui.QGridLayout(group_map)
502
+
503
+ self.setWindowTitle("Graph Window")
504
+ group_map.setTitle("Map Settings")
505
+ group_cp.setTitle('Cross Plot Settings')
506
+
507
+ lbl_combo_left = QtGui.QLabel()
508
+ lbl_combo2_left = QtGui.QLabel()
509
+ lbl_combo3_left = QtGui.QLabel()
510
+ lbl_combo_right = QtGui.QLabel()
511
+ lbl_combo2_right = QtGui.QLabel()
512
+
513
+ lbl_combo_left.setText('X Data Band:')
514
+ lbl_combo2_left.setText('Y Data Band:')
515
+ lbl_combo3_left.setText('Cluster Overlay:')
516
+ self.cp_dpoly.setText('Delete Polygon')
517
+ lbl_combo_right.setText('Data Band:')
518
+ lbl_combo2_right.setText('Cluster Overlay:')
519
+ self.map_dpoly.setText('Delete Polygon')
520
+
521
+ grid_left.addWidget(lbl_combo_left, 0, 0, 1, 1)
522
+ grid_left.addWidget(lbl_combo2_left, 1, 0, 1, 1)
523
+ grid_left.addWidget(lbl_combo3_left, 2, 0, 1, 1)
524
+ grid_left.addWidget(self.cp_dpoly, 0, 2, 1, 1)
525
+ grid_left.addWidget(self.cp_combo, 0, 1, 1, 1)
526
+ grid_left.addWidget(self.cp_combo2, 1, 1, 1, 1)
527
+ grid_left.addWidget(self.cp_combo3, 2, 1, 1, 1)
528
+ grid_right.addWidget(lbl_combo_right, 0, 0, 1, 1)
529
+ grid_right.addWidget(lbl_combo2_right, 1, 0, 1, 1)
530
+ grid_right.addWidget(self.map_dpoly, 0, 2, 1, 1)
531
+ grid_right.addWidget(self.map_combo, 0, 1, 1, 1)
532
+ grid_right.addWidget(self.map_combo2, 1, 1, 1, 1)
533
+ grid_main.addWidget(self.hist, 0, 0, 1, 1)
534
+ grid_main.addWidget(self.map, 0, 1, 1, 1)
535
+ grid_main.addWidget(group_cp, 1, 0, 1, 1)
536
+ grid_main.addWidget(group_map, 1, 1, 1, 1)
537
+
538
+ self.cp_dpoly.clicked.connect(self.on_cp_dpoly)
539
+ self.map_dpoly.clicked.connect(self.on_map_dpoly)
540
+
541
+ def on_cp_dpoly(self):
542
+ """ cp dpoly """
543
+ self.hist.polyi.new_poly([[10, 10]])
544
+ dattmp = self.map.csp.get_array()
545
+ dattmp.mask = np.zeros_like(dattmp.mask)
546
+ self.map.csp.changed()
547
+ self.map.figure.canvas.draw()
548
+
549
+ def on_map_dpoly(self):
550
+ """ map dpoly """
551
+ self.map.polyi.new_poly([[10, 10]])
552
+ dattmp = self.hist.csp.get_array()
553
+ dattmp.mask = np.ma.masked_equal(dattmp.data, 0.).mask
554
+ self.hist.csp.changed()
555
+ self.hist.figure.canvas.draw()
556
+
557
+ def on_cp_combo(self):
558
+ """ On Combo """
559
+ gstmp = self.cp_combo.currentIndex()
560
+ if gstmp != self.c[0]:
561
+ self.c[0] = gstmp
562
+ self.hist.update_graph(clearaxis=True)
563
+
564
+ def on_cp_combo2(self):
565
+ """ On Combo 2 """
566
+ gstmp = self.cp_combo2.currentIndex()
567
+ if gstmp != self.c[1]:
568
+ self.c[1] = gstmp
569
+ self.hist.update_graph(clearaxis=True)
570
+
571
+ def on_cp_combo3(self):
572
+ """ On combo 3 """
573
+ self.c[2] = self.cp_combo3.currentIndex()
574
+ self.hist.update_graph()
575
+
576
+ def on_map_combo(self):
577
+ """ On map combo """
578
+ self.m[0] = self.map_combo.currentIndex()
579
+ self.map.update_graph()
580
+
581
+ def on_map_combo2(self):
582
+ """ On map combo 2 """
583
+ self.m[1] = self.map_combo2.currentIndex()
584
+ self.map.update_graph()
585
+
586
+ def settings(self):
587
+ """ run """
588
+ if 'Raster' not in self.indata:
589
+ self.parent.showprocesslog('Error: You must have a multi-band ' +
590
+ 'raster dataset in addition to your' +
591
+ ' cluster analysis results')
592
+ return False
593
+
594
+ self.dat_tmp = self.indata['Raster']
595
+ self.map.data = self.indata['Raster']
596
+ self.hist.data = self.indata['Raster']
597
+
598
+ bands = [i.dataid for i in self.indata['Raster']]
599
+
600
+ self.cp_combo.clear()
601
+ self.cp_combo2.clear()
602
+ self.map_combo.clear()
603
+
604
+ self.cp_combo.addItems(bands)
605
+ self.cp_combo2.addItems(bands)
606
+ self.map_combo.addItems(bands)
607
+ self.cp_combo2.setCurrentIndex(1)
608
+ self.cp_combo.currentIndexChanged.connect(self.on_cp_combo)
609
+ self.cp_combo2.currentIndexChanged.connect(self.on_cp_combo2)
610
+ self.map_combo.currentIndexChanged.connect(self.on_map_combo)
611
+
612
+ cbands = ['Scatter Amplitudes']
613
+ mbands = ['None']
614
+
615
+ if 'Cluster' in self.indata:
616
+ self.hist.cdata = self.indata['Cluster']
617
+ self.map.cdata = self.indata['Cluster']
618
+ cbands += ['Clusters: ' + str(i.data.ptp()) for i in
619
+ self.indata['Cluster']]
620
+ mbands += ['Clusters: ' + str(i.data.ptp()) for i in
621
+ self.indata['Cluster']]
622
+
623
+ self.cp_combo3.clear()
624
+ self.map_combo2.clear()
625
+
626
+ self.cp_combo3.addItems(cbands)
627
+ self.map_combo2.addItems(mbands)
628
+ self.cp_combo3.currentIndexChanged.connect(self.on_cp_combo3)
629
+ self.map_combo2.currentIndexChanged.connect(self.on_map_combo2)
630
+
631
+ self.hist.init_graph()
632
+ self.map.init_graph()
633
+
634
+ self.show()
635
+
636
+ self.hist.polyint()
637
+ self.map.polyint()
638
+
639
+ self.hist.polyi.polyi_changed.connect(self.update_map)
640
+ self.map.polyi.polyi_changed.connect(self.update_hist)
641
+
642
+ return True
643
+
644
+ def update_map(self, polymask):
645
+ """ update """
646
+ if max(polymask) is False:
647
+ return
648
+ polymask = np.array(polymask)
649
+ dattmp = self.map.csp.get_array()
650
+ dattmp.mask = polymask
651
+ self.map.csp.changed()
652
+ self.map.figure.canvas.draw()
653
+
654
+ def update_hist(self, polymask):
655
+ """ update """
656
+ if max(polymask) is False:
657
+ return
658
+
659
+ polymask = np.array(polymask)
660
+ dattmp = self.hist.csp.get_array()
661
+ atmp = np.array([self.hist.xcoord[polymask],
662
+ self.hist.ycoord[polymask]]).T
663
+ dattmp.mask = np.ones_like(dattmp.mask)
664
+ for i in atmp:
665
+ dattmp.mask[i[1], i[0]] = False
666
+ self.hist.csp.changed()
667
+ self.hist.figure.canvas.draw()