1 from builtins
import range
2 from builtins
import object
27 import matplotlib.colors
28 from mpl_toolkits.axes_grid1
import make_axes_locatable
29 import mpl_toolkits.mplot3d
31 from .densityPlot
import mergeDefaults, hide_xticklabels, hide_yticklabels
32 from ..
import modelfitLib
34 __all__ = (
"OptimizerDisplay", )
43 self.
grid = parent.unitGrid * sample.get(parent.recorder.trust)
45 self.
grid += sample.get(parent.recorder.parameters).reshape((1,)*parent.ndim + (parent.ndim,))
52 return self.sample.get(getattr(self.parent.recorder, name))
58 self.parent.objective.fillObjectiveValueGrid(self.grid.reshape(-1, self.parent.ndim),
59 self._objectiveValues.reshape(-1))
68 self.parent.recorder.fillObjectiveModelGrid(self.
sample,
69 self.grid.reshape(-1, self.parent.ndim),
70 self._objectiveModel.reshape(-1))
76 def __init__(self, history, model, objective, steps=11):
77 self.
recorder = modelfitLib.OptimizerHistoryRecorder(history.schema)
79 self.
dimensions = list(model.getNonlinearNames()) + list(model.getAmplitudeNames())
87 mgridArgs = (slice(-1.0, 1.0, steps*1j),) * self.
ndim
89 transposeArgs = tuple(list(range(1, self.
ndim+1)) + [0])
90 self.
unitGrid = numpy.mgrid[mgridArgs].transpose(transposeArgs).copy()
92 for sample
in history:
93 if sample.get(self.recorder.state) & modelfitLib.Optimizer.STATUS_STEP_REJECTED:
94 assert current
is not None
95 current.rejected.append(sample)
98 self.track.append(current)
100 def plot(self, xDim, yDim, n=0):
110 self.
j = self.parent.dimensions.index(self.
xDim)
111 self.
i = self.parent.dimensions.index(self.
yDim)
112 self.
yKey = self.parent.recorder.parameters[self.
i]
113 self.
xKey = self.parent.recorder.parameters[self.
j]
114 self.
zKey = self.parent.recorder.objective
116 self.
slice2d = [s//2
for s
in self.parent.unitGrid.shape[:-1]]
120 self.
sliceX = [s//2
for s
in self.parent.unitGrid.shape[:-1]]
121 self.
sliceX[self.
j] = slice(
None)
123 self.
sliceY = [s//2
for s
in self.parent.unitGrid.shape[:-1]]
124 self.
sliceY[self.
i] = slice(
None)
127 x=numpy.array([iteration.sample.get(self.
xKey)
for iteration
in self.parent.track]),
128 y=numpy.array([iteration.sample.get(self.
yKey)
for iteration
in self.parent.track]),
129 z=numpy.array([iteration.sample.get(self.
zKey)
for iteration
in self.parent.track]),
132 self.
figure = matplotlib.pyplot.figure(
"%s vs %s" % (xDim, yDim), figsize=(16, 8))
133 self.figure.subplots_adjust(left=0.025, right=0.975, bottom=0.08, top=0.95, wspace=0.12)
134 self.
axes3d = self.figure.add_subplot(1, 2, 1, projection=
'3d')
135 self.axes3d.autoscale(
False)
136 self.axes3d.set_xlabel(self.
xDim)
137 self.axes3d.set_ylabel(self.
yDim)
138 self.
axes2d = self.figure.add_subplot(1, 2, 2)
139 self.axes2d.set_xlabel(self.
xDim)
140 self.axes2d.set_ylabel(self.
yDim)
141 self.axes2d.autoscale(
False)
142 divider = make_axes_locatable(self.
axes2d)
143 self.
axesX = divider.append_axes(
"top", 1.5, pad=0.1, sharex=self.
axes2d)
144 self.axesX.autoscale(
False, axis=
'x')
146 self.
axesY = divider.append_axes(
"right", 1.5, pad=0.1, sharey=self.
axes2d)
147 self.axesY.autoscale(
False, axis=
'y')
156 def xlim(self):
return self._extent[:2]
159 def ylim(self):
return self._extent[2:4]
162 def zlim(self):
return self._extent[4:]
165 current = self.parent.track[self.
n]
166 x = current.sample.get(self.
xKey)
167 y = current.sample.get(self.
yKey)
168 zMin1 = current.objectiveValues[self.
slice2d].min()
169 zMax1 = current.objectiveValues[self.
slice2d].max()
170 zMin2 = current.objectiveModel[self.
slice2d].min()
171 zMax2 = current.objectiveModel[self.
slice2d].max()
172 self.
setExtent(x0=x - current.trust, x1=x + current.trust,
173 y0=y - current.trust, y1=y + current.trust,
174 z0=min(zMin1, zMin2), z1=max(zMax1, zMax2), lock=
False)
176 def setExtent(self, x0=None, x1=None, y0=None, y1=None, z0=None, z1=None, lock=True):
189 self.
_extent = (x0, x1, y0, y1, z0, z1)
191 self.axes3d.set_xlim(*self.
xlim)
192 self.axes3d.set_ylim(*self.
ylim)
193 self.axes3d.set_zlim(*self.
zlim)
194 self.axes2d.set_xlim(*self.
xlim)
195 self.axes2d.set_ylim(*self.
ylim)
196 self.axesX.set_ylim(*self.
zlim)
197 self.axesY.set_xlim(*self.
zlim)
199 def _clipZ(self, x, y, z):
202 mask = numpy.logical_or.reduce([x < self.
xlim[0], x > self.
xlim[1],
204 z < self.
zlim[0], z > self.
zlim[1]],
208 return numpy.logical_not(mask).astype(int).sum() > 4
211 def _contour(self, axes, *args, **kwds):
212 self.artists.extend(axes.contour(*args, **kwds).collections)
215 kwds = dict(markeredgewidth=0, markerfacecolor=
'g', color=
'g', marker=
'o')
216 self.axes3d.plot(self.
track[
'x'], self.
track[
'y'], self.
track[
'z'], **kwds)
217 self.axes2d.plot(self.
track[
'x'], self.
track[
'y'], **kwds)
218 self.axesX.plot(self.
track[
'x'], self.
track[
'z'], **kwds)
219 self.axesY.plot(self.
track[
'z'], self.
track[
'y'], **kwds)
222 kwds = dict(markeredgewidth=0, markerfacecolor=
'r', color='r', marker='v')
223 current = self.parent.track[self.
n]
224 cx = current.sample.get(self.
xKey)
225 cy = current.sample.get(self.
yKey)
226 cz = current.sample.get(self.
zKey)
227 for r
in current.rejected:
228 x = [cx, r.get(self.
xKey)]
229 y = [cy, r.get(self.
yKey)]
230 z = [cz, r.get(self.
zKey)]
231 self.artists.extend(self.axes3d.plot(x, y, z, **kwds))
232 self.artists.extend(self.axes2d.plot(x, y, **kwds))
233 self.artists.extend(self.axesX.plot(x, z, **kwds))
234 self.artists.extend(self.axesY.plot(z, y, **kwds))
237 current = self.parent.track[self.
n]
240 x = current.grid[self.
slice2d + (self.
j,)]
241 y = current.grid[self.
slice2d + (self.
i,)]
242 z1 = current.objectiveValues[self.
slice2d].copy()
243 z2 = current.objectiveModel[self.
slice2d].copy()
244 norm = matplotlib.colors.Normalize(vmin=self.
zlim[0], vmax=self.
zlim[1])
246 self.
_contour(self.
axes2d, x, y, z1, cmap=matplotlib.cm.spring, norm=norm)
247 self.
_contour(self.
axes2d, x, y, z2, cmap=matplotlib.cm.winter, norm=norm)
251 self.
_contour(self.
axes3d, x, y, z1, cmap=matplotlib.cm.spring, norm=norm)
252 self.artists.append(self.axes3d.plot_surface(x, y, z1, rstride=1, cstride=1,
253 cmap=matplotlib.cm.spring, norm=norm,
254 linewidth=0, antialiased=1, alpha=0.5))
256 self.
_contour(self.
axes3d, x, y, z2, cmap=matplotlib.cm.winter, norm=norm)
257 self.artists.append(self.axes3d.plot_surface(x, y, z2, rstride=1, cstride=1,
258 cmap=matplotlib.cm.winter, norm=norm,
259 linewidth=0, antialiased=1, alpha=0.5))
262 self.artists.extend(self.axesX.plot(current.grid[self.
sliceX + (self.
j,)],
263 current.objectiveValues[self.
sliceX],
'm-'))
264 self.artists.extend(self.axesX.plot(current.grid[self.
sliceX + (self.
j,)],
265 current.objectiveModel[self.
sliceX],
'c-'))
266 self.artists.extend(self.axesY.plot(current.objectiveValues[self.
sliceY],
267 current.grid[self.
sliceY + (self.
i,)],
'm-'))
268 self.artists.extend(self.axesY.plot(current.objectiveModel[self.
sliceY],
269 current.grid[self.
sliceY + (self.
i,)],
'c-'))
284 self.figure.canvas.draw()