Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from builtins import range 

2import numpy as np 

3import matplotlib.pyplot as plt 

4import matplotlib.cm as cm 

5 

6from .plotHandler import BasePlotter 

7 

8#mag_sun = -27.1 # apparent r band magnitude of the sun. this sets the band for the magnitude limit. 

9# see http://www.ucolick.org/~cnaw/sun.html for apparent magnitudes in other bands. 

10mag_sun = -26.74 # apparent V band magnitude of the Sun (our H mags translate to V band) 

11km_per_au = 1.496e8 

12m_per_km = 1000 

13 

14 

15class MetricVsH(BasePlotter): 

16 """ 

17 Plot metric values versus H. 

18 Marginalize over metric values in each H bin using 'npReduce'. 

19 """ 

20 def __init__(self): 

21 self.plotType = 'MetricVsH' 

22 self.objectPlotter = False 

23 self.defaultPlotDict = {'title': None, 'xlabel': 'H (mag)', 'ylabel': None, 'label': None, 

24 'npReduce': None, 'nbins': None, 'albedo': None, 

25 'Hmark': None, 'HmarkLinestyle': ':', 'figsize': None} 

26 self.minHrange=1.0 

27 

28 def __call__(self, metricValue, slicer, userPlotDict, fignum=None): 

29 if 'linestyle' not in userPlotDict: 

30 userPlotDict['linestyle'] = '-' 

31 plotDict = {} 

32 plotDict.update(self.defaultPlotDict) 

33 plotDict.update(userPlotDict) 

34 fig = plt.figure(fignum, figsize=plotDict['figsize']) 

35 Hvals = slicer.slicePoints['H'] 

36 reduceFunc = plotDict['npReduce'] 

37 if reduceFunc is None: 

38 reduceFunc = np.mean 

39 if Hvals.shape[0] == 1: 

40 # We have a simple set of values to plot against H. 

41 # This may be due to running a summary metric, such as completeness. 

42 mVals = metricValue[0].filled() 

43 elif len(Hvals) == slicer.shape[1]: 

44 # Using cloned H distribution. 

45 # Apply 'npReduce' method directly to metric values, and plot at matching H values. 

46 mVals = reduceFunc(metricValue.filled(), axis=0) 

47 else: 

48 # Probably each object has its own H value. 

49 hrange = Hvals.max() - Hvals.min() 

50 minH = Hvals.min() 

51 if hrange < self.minHrange: 

52 hrange = self.minHrange 

53 minH = Hvals.min() - hrange/2.0 

54 nbins = plotDict['nbins'] 

55 if nbins is None: 

56 nbins = 30 

57 stepsize = hrange / float(nbins) 

58 bins = np.arange(minH, minH + hrange + stepsize/2.0, stepsize) 

59 # In each bin of H, calculate the 'npReduce' value of the corresponding metricValues. 

60 inds = np.digitize(Hvals, bins) 

61 inds = inds-1 

62 mVals = np.zeros(len(bins), float) 

63 for i in range(len(bins)): 

64 match = metricValue[inds == i] 

65 if len(match) == 0: 

66 mVals[i] = slicer.badval 

67 else: 

68 mVals[i] = reduceFunc(match.filled()) 

69 Hvals = bins 

70 plt.plot(Hvals, mVals, color=plotDict['color'], linestyle=plotDict['linestyle'], 

71 label=plotDict['label']) 

72 if 'xMin' in plotDict: 

73 plt.xlim(left = plotDict['xMin']) 

74 if 'xMax' in plotDict: 

75 plt.xlim(right = plotDict['xMax']) 

76 if 'yMin' in plotDict: 

77 plt.ylim(bottom = plotDict['yMin']) 

78 if 'yMax' in plotDict: 

79 plt.ylim(top = plotDict['yMax']) 

80 # Convert Hvals to diameter, using 'albedo' 

81 albedo = plotDict['albedo'] 

82 y = 1.0 

83 if albedo is not None: 

84 ax = plt.axes() 

85 ax2 = ax.twiny() 

86 Hmin, Hmax = ax.get_xlim() 

87 dmax = 2.0 * np.sqrt(10**((mag_sun - Hmin - 2.5*np.log10(albedo))/2.5)) 

88 dmin = 2.0 * np.sqrt(10**((mag_sun - Hmax - 2.5*np.log10(albedo))/2.5)) 

89 dmax = dmax * km_per_au * m_per_km 

90 dmin = dmin * km_per_au * m_per_km 

91 ax2.set_xlim(dmax, dmin) 

92 ax2.set_xscale('log') 

93 ax2.set_xlabel('D (m)', labelpad=-10, horizontalalignment='right') 

94 ax2.grid(False) 

95 plt.sca(ax) 

96 y = 1.1 

97 plt.grid(True) 

98 if plotDict['Hmark'] is not None: 

99 plt.axvline(x=plotDict['Hmark'], color='r', 

100 linestyle=plotDict['HmarkLinestyle'], alpha=0.3) 

101 plt.title(plotDict['title'], y=y) 

102 plt.xlabel(plotDict['xlabel']) 

103 plt.ylabel(plotDict['ylabel']) 

104 plt.tight_layout() 

105 return fig.number 

106 

107 

108class MetricVsOrbit(BasePlotter): 

109 """ 

110 Plot metric values (at a particular H value) vs. orbital parameters. 

111 Marginalize over metric values in each orbital bin using 'npReduce'. 

112 """ 

113 def __init__(self, xaxis='q', yaxis='e'): 

114 self.plotType = 'MetricVsOrbit_%s%s' %(xaxis, yaxis) 

115 self.objectPlotter = False 

116 self.defaultPlotDict = {'title': None, 'xlabel': xaxis, 'ylabel': yaxis, 

117 'xaxis': xaxis, 'yaxis': yaxis, 

118 'label': None, 'cmap': cm.viridis, 

119 'npReduce': None, 

120 'nxbins': None, 'nybins': None, 'levels': None, 

121 'Hval': None, 'Hwidth': None, 'figsize': None} 

122 

123 def __call__(self, metricValue, slicer, userPlotDict, fignum=None): 

124 plotDict = {} 

125 plotDict.update(self.defaultPlotDict) 

126 plotDict.update(userPlotDict) 

127 fig = plt.figure(fignum, figsize=plotDict['figsize']) 

128 xvals = slicer.slicePoints['orbits'][plotDict['xaxis']] 

129 yvals = slicer.slicePoints['orbits'][plotDict['yaxis']] 

130 # Set x/y bins. 

131 nxbins = plotDict['nxbins'] 

132 nybins = plotDict['nybins'] 

133 if nxbins is None: 

134 nxbins = 100 

135 if nybins is None: 

136 nybins = 100 

137 if 'xbins' in plotDict: 

138 xbins = plotDict['xbins'] 

139 else: 

140 xbinsize = (xvals.max() - xvals.min())/float(nxbins) 

141 xbins = np.arange(xvals.min(), xvals.max() + xbinsize/2.0, xbinsize) 

142 if 'ybins' in plotDict: 

143 ybins = plotDict['ybins'] 

144 else: 

145 ybinsize = (yvals.max() - yvals.min())/float(nybins) 

146 ybins = np.arange(yvals.min(), yvals.max() + ybinsize/2.0, ybinsize) 

147 nxbins = len(xbins) 

148 nybins = len(ybins) 

149 # Identify the relevant metricValues for the Hvalue we want to plot. 

150 Hvals = slicer.slicePoints['H'] 

151 Hwidth = plotDict['Hwidth'] 

152 if Hwidth is None: 

153 Hwidth = 1.0 

154 if len(Hvals) == slicer.shape[1]: 

155 if plotDict['Hval'] is None: 

156 Hidx = int(len(Hvals) / 2) 

157 Hval = Hvals[Hidx] 

158 else: 

159 Hval = plotDict['Hval'] 

160 Hidx = np.where(np.abs(Hvals - Hval) == np.abs(Hvals - Hval).min())[0] 

161 Hidx = Hidx[0] 

162 else: 

163 if plotDict['Hval'] is None: 

164 Hval = np.median(Hvals) 

165 Hidx = np.where(np.abs(Hvals - Hval) <= Hwidth/2.0)[0] 

166 else: 

167 Hval = plotDict['Hvals'] 

168 Hidx = np.where(np.abs(Hvals - Hval) <= Hwidth/2.0)[0] 

169 if len(Hvals) == slicer.shape[1]: 

170 mVals = np.swapaxes(metricValue, 1, 0)[Hidx].filled() 

171 else: 

172 mVals = metricValue[Hidx].filled() 

173 # Calculate the npReduce'd metric values at each x/y bin. 

174 if 'colorMin' in plotDict: 

175 badval = plotDict['colorMin'] - 1 

176 else: 

177 badval = slicer.badval 

178 binvals = np.zeros((nybins, nxbins), dtype='float') + badval 

179 xidxs = np.digitize(xvals, xbins) - 1 

180 yidxs = np.digitize(yvals, ybins) - 1 

181 reduceFunc = plotDict['npReduce'] 

182 if reduceFunc is None: 

183 reduceFunc = np.mean 

184 for iy in range(nybins): 

185 ymatch = np.where(yidxs == iy)[0] 

186 for ix in range(nxbins): 

187 xmatch = np.where(xidxs[ymatch] == ix)[0] 

188 matchVals = mVals[ymatch][xmatch] 

189 if len(matchVals) > 0: 

190 binvals[iy][ix] = reduceFunc(matchVals) 

191 xi, yi = np.meshgrid(xbins, ybins) 

192 if 'colorMin' in plotDict: 

193 vMin = plotDict['colorMin'] 

194 else: 

195 vMin = binvals.min() 

196 if 'colorMax' in plotDict: 

197 vMax = plotDict['colorMax'] 

198 else: 

199 vMax = binvals.max() 

200 nlevels = plotDict['levels'] 

201 if nlevels is None: 

202 nlevels = 200 

203 levels = np.arange(vMin, vMax, (vMax-vMin)/float(nlevels)) 

204 plt.contourf(xi, yi, binvals, levels, extend='max', 

205 zorder=0, cmap=plotDict['cmap']) 

206 cbar = plt.colorbar() 

207 label = plotDict['label'] 

208 if label is None: 

209 label = '' 

210 cbar.set_label(label + ' @ H=%.1f' %(Hval)) 

211 plt.title(plotDict['title']) 

212 plt.xlabel(plotDict['xlabel']) 

213 plt.ylabel(plotDict['ylabel']) 

214 return fig.number 

215 

216class MetricVsOrbitPoints(BasePlotter): 

217 """ 

218 Plot metric values (at a particular H value) as function of orbital parameters, 

219 using points for each metric value. 

220 """ 

221 def __init__(self, xaxis='q', yaxis='e'): 

222 self.plotType = 'MetricVsOrbit' 

223 self.objectPlotter = False 

224 self.defaultPlotDict = {'title': None, 'xlabel': xaxis, 'ylabel': yaxis, 

225 'label': None, 'cmap': cm.viridis, 

226 'xaxis': xaxis, 'yaxis': yaxis, 

227 'Hval': None, 'Hwidth': None, 

228 'foregroundPoints': True, 'backgroundPoints': False, 

229 'figsize': None} 

230 

231 def __call__(self, metricValue, slicer, userPlotDict, fignum=None): 

232 plotDict = {} 

233 plotDict.update(self.defaultPlotDict) 

234 plotDict.update(userPlotDict) 

235 fig = plt.figure(fignum, figsize=plotDict['figsize']) 

236 xvals = slicer.slicePoints['orbits'][plotDict['xaxis']] 

237 yvals = slicer.slicePoints['orbits'][plotDict['yaxis']] 

238 # Identify the relevant metricValues for the Hvalue we want to plot. 

239 Hvals = slicer.slicePoints['H'] 

240 Hwidth = plotDict['Hwidth'] 

241 if Hwidth is None: 

242 Hwidth = 1.0 

243 if len(Hvals) == slicer.shape[1]: 

244 if plotDict['Hval'] is None: 

245 Hidx = int(len(Hvals) / 2) 

246 Hval = Hvals[Hidx] 

247 else: 

248 Hval = plotDict['Hval'] 

249 Hidx = np.where(np.abs(Hvals - Hval) == np.abs(Hvals - Hval).min())[0] 

250 Hidx = Hidx[0] 

251 else: 

252 if plotDict['Hval'] is None: 

253 Hval = np.median(Hvals) 

254 Hidx = np.where(np.abs(Hvals - Hval) <= Hwidth/2.0)[0] 

255 else: 

256 Hval = plotDict['Hvals'] 

257 Hidx = np.where(np.abs(Hvals - Hval) <= Hwidth/2.0)[0] 

258 if len(Hvals) == slicer.shape[1]: 

259 mVals = np.swapaxes(metricValue, 1, 0)[Hidx] 

260 else: 

261 mVals = metricValue[Hidx] 

262 if 'colorMin' in plotDict: 

263 vMin = plotDict['colorMin'] 

264 else: 

265 vMin = mVals.min() 

266 if 'colorMax' in plotDict: 

267 vMax = plotDict['colorMax'] 

268 else: 

269 vMax = mVals.max() 

270 if plotDict['backgroundPoints']: 

271 # This isn't quite right for the condition .. but will do for now. 

272 condition = np.where(mVals == 0) 

273 plt.plot(xvals[condition], yvals[condition], 'r.', markersize=4, alpha=0.5, zorder=3) 

274 if plotDict['foregroundPoints']: 

275 plt.scatter(xvals, yvals, c=mVals, vmin=vMin, vmax=vMax, 

276 cmap=plotDict['cmap'], s=15, alpha=0.8, zorder=0) 

277 cbar = plt.colorbar() 

278 label = plotDict['label'] 

279 if label is None: 

280 label = '' 

281 cbar.set_label(label + ' @ H=%.1f' %(Hval)) 

282 plt.title(plotDict['title']) 

283 plt.xlabel(plotDict['xlabel']) 

284 plt.ylabel(plotDict['ylabel']) 

285 return fig.number