Skip to content

Commit 8953dda

Browse files
authored
Merge pull request #14 from Smithsonian/plotting
Merge Plotting into Master
2 parents b8f55cf + 1e332a2 commit 8953dda

2 files changed

Lines changed: 260 additions & 1 deletion

File tree

src/graspfile/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212

1313
__version__ = '0.3.1'
1414

15-
__all__ = ['cut', 'grid', 'torfile', 'torparser']
15+
__all__ = ['cut', 'grid', 'plot', 'torfile', 'torparser']

src/graspfile/plot/__init__.py

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
import numpy as np
2+
from matplotlib import pyplot as pp
3+
4+
5+
# Function to get list of axes for plotting
6+
def get_axes(n_axes, ax_label=None, ay_label=None):
7+
"""Generate a set of axes ready for plotting multiple fields or grids.
8+
9+
Args:
10+
n_axes int: number of axes to generate.
11+
ax_label str: label for x axes. Only shown on bottom axes.
12+
ay_label str: label for y axes. Only shown on left-most axes.
13+
14+
Returns:
15+
``matplotlib.Figure``: figure object.
16+
list: of ``matplotlib.Axes``: list of individual subplot axes.
17+
"""
18+
if n_axes > 9:
19+
pp.rcParams['figure.figsize'] = 12, 16
20+
fig, axes_array = pp.subplots(4, 3)
21+
elif n_axes > 6:
22+
pp.rcParams['figure.figsize'] = 12, 12
23+
fig, axes_array = pp.subplots(3, 3)
24+
elif n_axes > 4:
25+
pp.rcParams['figure.figsize'] = 12, 9
26+
fig, axes_array = pp.subplots(2, 3)
27+
elif n_axes > 2:
28+
pp.rcParams['figure.figsize'] = 12, 9
29+
fig, axes_array = pp.subplots(2, 2)
30+
elif n_axes == 2:
31+
pp.rcParams['figure.figsize'] = 12, 9
32+
fig, axs = pp.subplots(1, 2)
33+
axes_array = [axs]
34+
else: # One feed only
35+
fig, ax = pp.subplots(1, 1)
36+
axes_array = [[ax]]
37+
38+
# Turn off all axes, and then turn them on when we use them
39+
for ax in axes_array.flatten():
40+
ax.axis('off')
41+
# Set X label for the bottom row of plots
42+
for ax in axes_array[-1, :]:
43+
ax.set_xlabel(ax_label)
44+
# Set Y label for the first column of plots
45+
for ax in axes_array[:, 0]:
46+
ax.set_ylabel(ay_label)
47+
# Turn off ticklabels for plots not on bottom row or left column
48+
try:
49+
for ax in axes_array[:-1, :].flatten():
50+
ax.set_xticklabels([])
51+
except IndexError:
52+
pass
53+
try:
54+
for ax in axes_array[:, 1:].flatten():
55+
ax.set_yticklabels([])
56+
except IndexError:
57+
pass
58+
59+
axes = axes_array.flatten()
60+
61+
return fig, axes
62+
63+
64+
def get_max_fields(fields, step, component=0, db=True):
65+
"""Finds the maximum amplitude in the set of fields and return a suitable common limit for plotting all fields.
66+
67+
Returns the next value equal to n x step above the maximum amplitude found.
68+
69+
Args:
70+
fields (list: of :obj:`GraspField`): the set of fields to determine common limits for.
71+
step (float): Step size to change the limit by.
72+
component (int): index of the field component to use.
73+
db (bool): Work in db(amplitude)
74+
75+
Returns:
76+
float: limit suitable for plotting all fields."""
77+
if db:
78+
limit = -1000.0
79+
else:
80+
limit = 0.0
81+
82+
for field in fields:
83+
if db:
84+
data = 20 * np.log10(np.abs(field.field[:, :, component]))
85+
else:
86+
data = np.abs(field.field[:, :, component])
87+
88+
max_data = np.amax(data)
89+
if not db:
90+
step = max_data / 10.0
91+
if max_data > limit:
92+
limit = step * np.ceil(max_data / step)
93+
94+
return limit
95+
96+
97+
def plot_amplitude_fields(fields, component, suptitle=None, titles=None, xlabel=None, ylabel=None, vlabel=None,
98+
limits=None, db=True, cmap="gist_heat"):
99+
"""Plot all of the fields supplied as subplots in a single figure.
100+
101+
Args:
102+
fields (list: of :obj:`GraspField`): set of fields to plot.
103+
component (int:): field component to plot.
104+
suptitle (str:): title to use for overall figure.
105+
titles (list: of str:): titles to use for each field.
106+
xlabel (str:): x axis label.
107+
ylabel (str:): y axis label.
108+
vlabel (str:): colorbar label.
109+
limits (tuple: of float:): lower and upper limits for color scale. If not given, will default to 0 to max for
110+
absolute, ~40 db below maximum for db.
111+
db (bool:): plot db (or absolute):
112+
cmap (str:): name of matplotlib cmap to use
113+
114+
Returns:
115+
:obj: `matplotlib.Figure`: matplotlib Figure containing the plots.
116+
"""
117+
fig, axes = get_axes(len(fields), xlabel, ylabel)
118+
119+
if limits:
120+
v_min = limits[0]
121+
v_max = limits[1]
122+
else:
123+
step = 2
124+
v_max = get_max_fields(fields, step, component, db)
125+
if db:
126+
v_min = v_max - 40.0
127+
else:
128+
v_min = 0.0
129+
130+
for f, field in enumerate(fields):
131+
ax = axes[f]
132+
ax.axis('on')
133+
134+
if db:
135+
im = ax.imshow(20 * np.log10(np.abs(field.field[:, :, component])),
136+
cmap=cmap, interpolation=None, origin="lower",
137+
extent=[field.grid_min_x, field.grid_max_x, field.grid_min_y, field.grid_max_y],
138+
vmin=v_min, vmax=v_max)
139+
else:
140+
im = ax.imshow((np.abs(field.field[:, :, component])),
141+
cmap=cmap, interpolation=None, origin="lower",
142+
extent=[field.grid_min_x, field.grid_max_x, field.grid_min_y, field.grid_max_y],
143+
vmin=v_min, vmax=v_max)
144+
ax.grid(color='w', linestyle='--')
145+
if titles:
146+
ax.set_title(titles[f])
147+
148+
fig.suplots_adjust(right=0.85)
149+
cbar_ax = fig.add_axes([0.87, 0.13, 0.02, 0.7])
150+
cbar = fig.colorbar(im, cax=cbar_ax)
151+
cbar.ax.set_ylabel(vlabel)
152+
153+
fig.suptitle(suptitle)
154+
155+
return fig
156+
157+
158+
def plot_amplitude_grids(grids, field, component, suptitle=None, titles=None, xlabel=None, ylabel=None, vlabel=None,
159+
limits=None, db=True, cmap="gist_heat"):
160+
"""Plot all of the fields supplied as subplots in a single figure.
161+
162+
Args:
163+
grids (list: of :obj:`GraspField`): set of grids to plot.
164+
field (int:): index of field from each grid to plot.
165+
component (int:): field component to plot.
166+
suptitle (str:): title to use for overall figure.
167+
titles (list: of str:): titles to use for each field.
168+
xlabel (str:): x axis label.
169+
ylabel (str:): y axis label.
170+
vlabel (str:): colorbar label.
171+
limits (tuple: of float:): lower and upper limits for color scale.
172+
db (bool:): plot db (or absolute):
173+
cmap (str:): name of matplotlib cmap to use
174+
175+
Returns:
176+
:obj: `matplotlib.Figure`: matplotlib Figure containing the plots.
177+
"""
178+
fields = []
179+
for grid in grids:
180+
fields.append(grid.fields[field])
181+
182+
return plot_amplitude_fields(fields, component, suptitle, titles, xlabel, ylabel, vlabel, limits, db, cmap)
183+
184+
185+
def plot_phase_fields(fields, component, suptitle=None, titles=None, xlabel=None, ylabel=None, vlabel=None,
186+
limits=None, cmap="jet"):
187+
"""Plot the phase of all of the fields supplied as subplots in a single figure.
188+
189+
Args:
190+
fields (list: of :obj:`GraspField`): set of fields to plot.
191+
component (int:): field component to plot.
192+
suptitle (str:): title to use for overall figure.
193+
titles (list: of str:): titles to use for each field.
194+
xlabel (str:): x axis label.
195+
ylabel (str:): y axis label.
196+
vlabel (str:): colorbar label.
197+
limits (tuple: of float:): lower and upper limits for color scale. If not given, plots will be from -180 to 180
198+
db (bool:): plot db (or absolute):
199+
cmap (str:): name of matplotlib cmap to use
200+
201+
Returns:
202+
:obj: `matplotlib.Figure`: matplotlib Figure containing the plots.
203+
"""
204+
fig, axes = get_axes(len(fields), xlabel, ylabel)
205+
206+
if limits:
207+
v_min = limits[0]
208+
v_max = limits[1]
209+
else:
210+
v_min = -180.0
211+
v_max = 180.0
212+
213+
for f, field in enumerate(fields):
214+
ax = axes[f]
215+
ax.axis('on')
216+
217+
im = ax.imshow(np.angle(field.field[:, :, component], deg=True),
218+
cmap=cmap, interpolation=None, origin="lower",
219+
extent=[field.grid_min_x, field.grid_max_x, field.grid_min_y, field.grid_max_y],
220+
vmin=v_min, vmax=v_max)
221+
ax.grid(color='w', linestyle='--')
222+
if titles:
223+
ax.set_title(titles[f])
224+
225+
fig.suplots_adjust(right=0.85)
226+
cbar_ax = fig.add_axes([0.87, 0.13, 0.02, 0.7])
227+
cbar = fig.colorbar(im, cax=cbar_ax)
228+
cbar.ax.set_ylabel(vlabel)
229+
230+
fig.suptitle(suptitle)
231+
232+
return fig
233+
234+
235+
def plot_phase_grids(grids, field, component, suptitle=None, titles=None, xlabel=None, ylabel=None, vlabel=None,
236+
limits=None, cmap="jet"):
237+
"""Plot the phase of all of the grids supplied as subplots in a single figure.
238+
239+
Args:
240+
grids (list: of :obj:`GraspField`): set of fields to plot.
241+
field (int:): index of field from each grid to plot.
242+
component (int:): field component to plot.
243+
suptitle (str:): title to use for overall figure.
244+
titles (list: of str:): titles to use for each field.
245+
xlabel (str:): x axis label.
246+
ylabel (str:): y axis label.
247+
vlabel (str:): colorbar label.
248+
limits (tuple: of float:): lower and upper limits for color scale. If not given, plots will be from -180 to 180
249+
db (bool:): plot db (or absolute):
250+
cmap (str:): name of matplotlib cmap to use
251+
252+
Returns:
253+
:obj: `matplotlib.Figure`: matplotlib Figure containing the plots.
254+
"""
255+
fields = []
256+
for grid in grids:
257+
fields.append(grid.fields[field])
258+
259+
return plot_phase_fields(fields, component, suptitle, titles, xlabel, ylabel, vlabel, limits, cmap)

0 commit comments

Comments
 (0)