Coverage for python/lsst/sims/maf/plots/ndPlotters.py : 12%

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
9__all__ = ['TwoDSubsetData', 'OneDSubsetData']
11perceptual_rainbow = makePRCmap()
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}
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).
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
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}
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).
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