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 zip 

2from builtins import range 

3import numpy as np 

4import matplotlib.pyplot as plt 

5from matplotlib import colors 

6from .plotHandler import BasePlotter 

7from .perceptual_rainbow import makePRCmap 

8 

9__all__ = ['TwoDSubsetData', 'OneDSubsetData'] 

10 

11perceptual_rainbow = makePRCmap() 

12 

13class TwoDSubsetData(BasePlotter): 

14 """ 

15 Plot 2 axes from the slicer.sliceColList, identified by 

16 plotDict['xaxis']/['yaxis'], given the metricValues at all 

17 slicepoints [sums over non-visible axes]. 

18 """ 

19 def __init__(self): 

20 self.plotType = '2DBinnedData' 

21 self.objectPlotter = False 

22 self.defaultPlotDict = {'title': None, 'xlabel': None, 'ylable': None, 'units': None, 

23 'logScale': False, 'clims': None, 'cmap': perceptual_rainbow, 

24 'cbarFormat': None} 

25 

26 def __call__(self, metricValues, slicer, userPlotDict, fignum=None): 

27 """ 

28 Parameters 

29 ---------- 

30 metricValue : numpy.ma.MaskedArray 

31 slicer : lsst.sims.maf.slicers.NDSlicer 

32 userPlotDict: dict 

33 Dictionary of plot parameters set by user (overrides default values). 

34 'xaxis' and 'yaxis' values define which axes of the nd data to plot along the x/y axes. 

35 fignum : int 

36 Matplotlib figure number to use (default = None, starts new figure). 

37 

38 Returns 

39 ------- 

40 int 

41 Matplotlib figure number used to create the plot. 

42 """ 

43 if slicer.slicerName != 'NDSlicer': 

44 raise ValueError('TwoDSubsetData plots ndSlicer metric values') 

45 fig = plt.figure(fignum) 

46 plotDict = {} 

47 plotDict.update(self.defaultPlotDict) 

48 plotDict.update(userPlotDict) 

49 if 'xaxis' not in plotDict or 'yaxis' not in plotDict: 

50 raise ValueError('xaxis and yaxis must be specified in plotDict') 

51 xaxis = plotDict['xaxis'] 

52 yaxis = plotDict['yaxis'] 

53 # Reshape the metric data so we can isolate the values to plot 

54 # (just new view of data, not copy). 

55 newshape = [] 

56 for b in slicer.bins: 

57 newshape.append(len(b) - 1) 

58 newshape.reverse() 

59 md = metricValues.reshape(newshape) 

60 # Sum over other dimensions. Note that masked values are not included in sum. 

61 sumaxes = list(range(slicer.nD)) 

62 sumaxes.remove(xaxis) 

63 sumaxes.remove(yaxis) 

64 sumaxes = tuple(sumaxes) 

65 md = md.sum(sumaxes) 

66 # Plot the histogrammed data. 

67 # Plot data. 

68 x, y = np.meshgrid(slicer.bins[xaxis][:-1], slicer.bins[yaxis][:-1]) 

69 if plotDict['logScale']: 

70 norm = colors.LogNorm() 

71 else: 

72 norm = None 

73 if plotDict['clims'] is None: 

74 im = plt.contourf(x, y, md, 250, norm=norm, extend='both', cmap=plotDict['cmap']) 

75 else: 

76 im = plt.contourf(x, y, md, 250, norm=norm, extend='both', cmap=plotDict['cmap'], 

77 vmin=plotDict['clims'][0], vmax=plotDict['clims'][1]) 

78 xlabel = plotDict['xlabel'] 

79 if xlabel is None: 

80 xlabel = slicer.sliceColList[xaxis] 

81 plt.xlabel(xlabel) 

82 ylabel = plotDict['ylabel'] 

83 if ylabel is None: 

84 ylabel = slicer.sliceColList[yaxis] 

85 plt.ylabel(ylabel) 

86 cb = plt.colorbar(im, aspect=25, extend='both', 

87 orientation='horizontal', format=plotDict['cbarFormat']) 

88 cb.set_label(plotDict['units']) 

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

90 return fig.number 

91 

92 

93class OneDSubsetData(BasePlotter): 

94 """ 

95 Plot a single axes from the sliceColList, identified by plotDict['axis'], 

96 given the metricValues at all slicepoints [sums over non-visible axes]. 

97 """ 

98 def __init__(self): 

99 self.plotType = '1DBinnedData' 

100 self.objectPlotter = False 

101 self.defaultPlotDict = {'title': None, 'xlabel': None, 'ylabel': None, 'label': None, 'units': None, 

102 'logScale': False, 'histRange': None, 'filled': False, 'alpha': 0.5, 

103 'cmap': perceptual_rainbow, 'cbarFormat': None} 

104 

105 def plotBinnedData1D(self, metricValues, slicer, userPlotDict, fignum=None): 

106 """ 

107 Parameters 

108 ---------- 

109 metricValue : numpy.ma.MaskedArray 

110 slicer : lsst.sims.maf.slicers.NDSlicer 

111 userPlotDict: dict 

112 Dictionary of plot parameters set by user (overrides default values). 

113 'axis' keyword identifies which axis to show in the plot (along xaxis of plot). 

114 fignum : int 

115 Matplotlib figure number to use (default = None, starts new figure). 

116 

117 Returns 

118 ------- 

119 int 

120 Matplotlib figure number used to create the plot. 

121 """ 

122 if slicer.slicerName != 'NDSlicer': 

123 raise ValueError('TwoDSubsetData plots ndSlicer metric values') 

124 fig = plt.figure(fignum) 

125 plotDict = {} 

126 plotDict.update(self.defaultPlotDict) 

127 plotDict.update(userPlotDict) 

128 if 'axis' not in plotDict: 

129 raise ValueError('axis for 1-d plot must be specified in plotDict') 

130 # Reshape the metric data so we can isolate the values to plot 

131 # (just new view of data, not copy). 

132 axis = plotDict['axis'] 

133 newshape = [] 

134 for b in slicer.bins: 

135 newshape.append(len(b) - 1) 

136 newshape.reverse() 

137 md = metricValues.reshape(newshape) 

138 # Sum over other dimensions. Note that masked values are not included in sum. 

139 sumaxes = list(range(slicer.nD)) 

140 sumaxes.remove(axis) 

141 sumaxes = tuple(sumaxes) 

142 md = md.sum(sumaxes) 

143 # Plot the histogrammed data. 

144 leftedge = slicer.bins[axis][:-1] 

145 width = np.diff(slicer.bins[axis]) 

146 if plotDict['filled']: 

147 plt.bar(leftedge, md, width, label=plotDict['label'], 

148 linewidth=0, alpha=plotDict['alpha'], log=plotDict['logScale']) 

149 else: 

150 x = np.ravel(list(zip(leftedge, leftedge + width))) 

151 y = np.ravel(list(zip(md, md))) 

152 if plotDict['logScale']: 

153 plt.semilogy(x, y, label=plotDict['label']) 

154 else: 

155 plt.plot(x, y, label=plotDict['label']) 

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

157 xlabel = plotDict['xlabel'] 

158 if xlabel is None: 

159 xlabel = slicer.sliceColName[axis] 

160 if plotDict['units'] != None: 

161 xlabel += ' (' + plotDict['units'] + ')' 

162 plt.xlabel(xlabel) 

163 if (plotDict['histRange'] != None): 

164 plt.xlim(plotDict['histRange']) 

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

166 return fig.number