Coverage for /home/andrew/Documents/Research/gwent/gwent/snrplot.py : 89%

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
1import numpy as np
2import matplotlib as mpl
3import matplotlib.pyplot as plt
4import matplotlib.colors as colors
5from scipy.constants import golden_ratio
7import astropy.units as u
8from astropy.cosmology import z_at_value
9from astropy.cosmology import WMAP9 as cosmo
12def Plot_SNR(
13 var_x,
14 sample_x,
15 var_y,
16 sample_y,
17 SNRMatrix,
18 fig=None,
19 ax=None,
20 display=True,
21 return_plt=False,
22 dl_axis=False,
23 lb_axis=False,
24 smooth_contours=True,
25 cfill=True,
26 display_cbar=True,
27 x_axis_label=True,
28 y_axis_label=True,
29 x_axis_line=None,
30 y_axis_line=None,
31 logLevels_min=-1.0,
32 logLevels_max=0.0,
33 hspace=0.15,
34 wspace=0.1,
35 contour_kwargs={},
36 contourf_kwargs={},
37 xticklabels_kwargs={},
38 xlabels_kwargs={},
39 xline_kwargs={},
40 yticklabels_kwargs={},
41 ylabels_kwargs={},
42 yline_kwargs={},
43):
44 """Plots the SNR contours from calcSNR
46 Parameters
47 ----------
48 fig : object
49 matplotlib figure object on which to collate the individual plots
50 ax : object
51 matplotlib axes object on which to plot the individual plot
52 var_x : str
53 x-axis variable
54 sample_x : array
55 samples at which SNRMatrix was calculated corresponding to the x-axis variable
56 var_y : str
57 y-axis variable
58 sample_y : array
59 samples at which SNRMatrix was calculated corresponding to the y-axis variable
60 SNRMatrix : array-like
61 the matrix at which the SNR was calculated corresponding to the particular x and y-axis variable choices
63 display : bool, optional
64 Option to turn off display if saving multiple plots to a file
65 return_plt : bool, optional
66 Option to return fig and ax
67 dl_axis : bool, optional
68 Option to turn on the right hand side labels of luminosity distance
69 smooth_contours : bool, optional
70 Option to interpolate contours to a finer mesh size to appear smooth instead of tiered contours
71 cfill : bool, optional
72 Option to use filled contours or not, default is True
73 display_cbar : bool, optional
74 Option to display the colorbar on the axes object
75 x_axis_label : bool, optional
76 Option to display the x axis label
77 y_axis_label : bool, optional
78 Option to display the y axis label
79 x_axis_line : int,float, optional
80 Option to display a line on the x axis if not None
81 y_axis_line : int,float, optional
82 Option to display a line on the y axis if not None
83 logLevels_min : float, optional
84 Sets the minimum log level of the colorbar, default is -1.0
85 logLevels_max : float, optional
86 Sets the maximum log level of the colorbar, default is 0.0, which sets the maximum to the log maximum value of SNRMatrix
87 hspace : float, optional
88 Sets the horizontal space between axes objects, default is 0.15
89 wspace : float, optional
90 Sets the horizontal space between axes objects, default is 0.1
91 contour_kwargs : dict, optional
92 Sets additional kwargs taken by contour in matplotlib
93 contourf_kwargs : dict, optional
94 Sets additional kwargs taken by contourf in matplotlib
95 xticklabels_kwargs : dict, optional
96 Sets additional kwargs taken by xticklabel in matplotlib
97 xlabels_kwargs= : dict, optional
98 Sets additional kwargs taken by xlabel in matplotlib
99 xline_kwargs : dict, optional
100 Sets additional kwargs taken by ax.axvline in matplotlib
101 yticklabels_kwargs : dict, optional
102 Sets additional kwargs taken by yticklabel in matplotlib
103 ylabels_kwargs : dict, optional
104 Sets additional kwargs taken by ylabel in matplotlib
105 yline_kwargs : dict, optional
106 Sets additional kwargs taken by ax.axhline in matplotlib
108 """
109 if fig is not None:
110 if ax is not None:
111 pass
112 else:
113 fig, ax = plt.subplots()
114 else:
115 fig, ax = plt.subplots()
117 if "colors" not in contour_kwargs.keys() and "cmap" not in contour_kwargs.keys():
118 contour_kwargs["colors"] = "k"
119 if "linewidths" not in contour_kwargs.keys():
120 contour_kwargs["linewidths"] = 2.0
122 if "cmap" not in contourf_kwargs.keys():
123 contourf_kwargs["cmap"] = "viridis"
125 logSNR = np.log10(SNRMatrix)
126 if logLevels_min == -1.0:
127 logLevels_min = np.log10(np.array([1.0]))
128 if logLevels_max == 0.0:
129 logLevels_max = np.ceil(np.amax(logSNR))
130 if logLevels_max < logLevels_min:
131 raise ValueError("All SNRs are lower than 5.")
133 logLevels_add = np.log10(np.array([3.0, 10.0, 31.0]))
134 print_logLevels = np.concatenate(
135 (logLevels_min, logLevels_add, np.arange(2.0, logLevels_max + 1.0))
136 )
138 logLevels = print_logLevels
140 ylabel_min = min(sample_y)
141 ylabel_max = max(sample_y)
142 xlabel_min = min(sample_x)
143 xlabel_max = max(sample_x)
145 # Set whether log or linearly spaced axes
146 if xlabel_max < 0.0 or xlabel_min < 0.0 or var_x in ["n_p", "T_obs"]:
147 xaxis_type = "lin"
148 step_size = int(xlabel_max - xlabel_min + 1)
149 x_labels = np.linspace(xlabel_min, xlabel_max, step_size)
150 else:
151 x_log_range = np.log10(xlabel_max) - np.log10(xlabel_min)
152 if x_log_range >= 2.0:
153 xaxis_type = "log"
154 step_size = int(np.log10(xlabel_max) - np.log10(xlabel_min) + 1)
155 x_labels = np.logspace(
156 np.log10(xlabel_min), np.log10(xlabel_max), step_size
157 )
158 else:
159 xaxis_type = "lin"
160 x_scale = 10 ** round(np.log10(xlabel_min))
161 x_labels = (
162 np.arange(
163 round(xlabel_min / x_scale), round(xlabel_max / x_scale) + 1, 1
164 )
165 * x_scale
166 )
167 if x_labels[0] < xlabel_min:
168 x_labels[0] = xlabel_min
169 if x_labels[-1] > xlabel_max:
170 x_labels[-1] = xlabel_max
172 if ylabel_max < 0.0 or ylabel_min < 0.0 or var_y in ["n_p", "T_obs"]:
173 yaxis_type = "lin"
174 step_size = int(ylabel_max - ylabel_min + 1)
175 y_labels = np.linspace(ylabel_min, ylabel_max, step_size)
176 else:
177 y_log_range = np.log10(ylabel_max) - np.log10(ylabel_min)
178 if y_log_range >= 2.0:
179 yaxis_type = "log"
180 step_size = int(np.log10(ylabel_max) - np.log10(ylabel_min) + 1)
181 y_labels = np.logspace(
182 np.log10(ylabel_min), np.log10(ylabel_max), step_size
183 )
184 else:
185 yaxis_type = "lin"
186 y_scale = 10 ** round(np.log10(ylabel_min))
187 y_labels = (
188 np.arange(
189 round(ylabel_min / y_scale), round(ylabel_max / y_scale) + 1, 1
190 )
191 * y_scale
192 )
193 if y_labels[0] < ylabel_min:
194 y_labels[0] = ylabel_min
195 if y_labels[-1] > ylabel_max:
196 y_labels[-1] = ylabel_max
198 # Set axis scales based on what data sampling we used
199 if yaxis_type == "lin" and xaxis_type == "log":
200 if cfill == False:
201 CS1 = ax.contour(
202 np.log10(sample_x), sample_y, logSNR, print_logLevels, **contour_kwargs
203 )
204 else:
205 if smooth_contours:
206 cmap = mpl.cm.get_cmap(name=contourf_kwargs["cmap"])
207 cmap.set_under(color="white")
208 CS1 = ax.imshow(
209 logSNR,
210 extent=[
211 np.log10(xlabel_min),
212 np.log10(xlabel_max),
213 ylabel_min,
214 ylabel_max,
215 ],
216 vmin=logLevels_min,
217 vmax=logLevels_max,
218 origin="lower",
219 aspect="auto",
220 cmap=cmap,
221 )
222 else:
223 CS1 = ax.contourf(
224 np.log10(sample_x), sample_y, logSNR, logLevels, **contourf_kwargs
225 )
226 ax.contour(
227 np.log10(sample_x), sample_y, logSNR, print_logLevels, **contour_kwargs
228 )
229 ax.set_xlim(np.log10(xlabel_min), np.log10(xlabel_max))
230 ax.set_ylim(ylabel_min, ylabel_max)
232 elif yaxis_type == "log" and xaxis_type == "lin":
233 if cfill == False:
234 CS1 = ax.contour(
235 sample_x, np.log10(sample_y), logSNR, print_logLevels, **contour_kwargs
236 )
237 else:
238 if smooth_contours:
239 cmap = mpl.cm.get_cmap(name=contourf_kwargs["cmap"])
240 cmap.set_under(color="white")
241 CS1 = ax.imshow(
242 logSNR,
243 extent=[
244 xlabel_min,
245 xlabel_max,
246 np.log10(ylabel_min),
247 np.log10(ylabel_max),
248 ],
249 vmin=logLevels_min,
250 vmax=logLevels_max,
251 origin="lower",
252 aspect="auto",
253 cmap=cmap,
254 )
255 else:
256 CS1 = ax.contourf(
257 sample_x, np.log10(sample_y), logSNR, logLevels, **contourf_kwargs
258 )
259 ax.contour(
260 sample_x, np.log10(sample_y), logSNR, print_logLevels, **contour_kwargs
261 )
262 ax.set_xlim(xlabel_min, xlabel_max)
263 ax.set_ylim(np.log10(ylabel_min), np.log10(ylabel_max))
264 elif yaxis_type == "lin" and xaxis_type == "lin":
265 if cfill == False:
266 CS1 = ax.contour(
267 sample_x, sample_y, logSNR, print_logLevels, **contour_kwargs
268 )
269 else:
270 if smooth_contours:
271 cmap = mpl.cm.get_cmap(name=contourf_kwargs["cmap"])
272 cmap.set_under(color="white")
273 CS1 = ax.imshow(
274 logSNR,
275 extent=[xlabel_min, xlabel_max, ylabel_min, ylabel_max],
276 vmin=logLevels_min,
277 vmax=logLevels_max,
278 origin="lower",
279 aspect="auto",
280 cmap=cmap,
281 )
282 else:
283 CS1 = ax.contourf(
284 sample_x, sample_y, logSNR, logLevels, **contourf_kwargs
285 )
286 ax.contour(sample_x, sample_y, logSNR, print_logLevels, **contour_kwargs)
287 ax.set_xlim(xlabel_min, xlabel_max)
288 ax.set_ylim(ylabel_min, ylabel_max)
289 else:
290 if cfill == False:
291 CS1 = ax.contour(
292 np.log10(sample_x),
293 np.log10(sample_y),
294 logSNR,
295 print_logLevels,
296 **contour_kwargs
297 )
298 else:
299 if smooth_contours:
300 cmap = mpl.cm.get_cmap(name=contourf_kwargs["cmap"])
301 cmap.set_under(color="white")
302 CS1 = ax.imshow(
303 logSNR,
304 extent=[
305 np.log10(xlabel_min),
306 np.log10(xlabel_max),
307 np.log10(ylabel_min),
308 np.log10(ylabel_max),
309 ],
310 vmin=logLevels_min,
311 vmax=logLevels_max,
312 origin="lower",
313 aspect="auto",
314 cmap=cmap,
315 interpolation="None",
316 )
317 else:
318 CS1 = ax.contourf(
319 np.log10(sample_x),
320 np.log10(sample_y),
321 logSNR,
322 logLevels,
323 **contourf_kwargs
324 )
325 ax.contour(
326 np.log10(sample_x),
327 np.log10(sample_y),
328 logSNR,
329 print_logLevels,
330 **contour_kwargs
331 )
332 ax.set_xlim(np.log10(xlabel_min), np.log10(xlabel_max))
333 ax.set_ylim(np.log10(ylabel_min), np.log10(ylabel_max))
335 Get_Axes_Labels(
336 ax,
337 "x",
338 var_x,
339 xaxis_type,
340 x_labels,
341 x_axis_line,
342 xlabels_kwargs,
343 xticklabels_kwargs,
344 xline_kwargs,
345 )
346 Get_Axes_Labels(
347 ax,
348 "y",
349 var_y,
350 yaxis_type,
351 y_labels,
352 y_axis_line,
353 ylabels_kwargs,
354 yticklabels_kwargs,
355 yline_kwargs,
356 )
358 if not x_axis_label:
359 ax.set_xticklabels("")
360 ax.set_xlabel("")
361 if not y_axis_label:
362 ax.set_yticklabels("")
363 ax.set_ylabel("")
365 # If true, display luminosity distance on right side of plot
366 if dl_axis:
367 if var_y != "z":
368 raise ValueError(
369 "Sorry, we can only plot luminosity distance when redshift is on the y axis."
370 )
372 # Set other side y-axis for luminosity distance scalings
373 ax2 = ax.twinx()
374 # Set axis scales based on what data sampling we used
375 if yaxis_type == "lin" and xaxis_type == "log":
376 ax2.contour(
377 np.log10(sample_x), sample_y, logSNR, print_logLevels, **contour_kwargs
378 )
379 elif yaxis_type == "log" and xaxis_type == "lin":
380 ax2.contour(
381 sample_x, np.log10(sample_y), logSNR, print_logLevels, **contour_kwargs
382 )
383 else:
384 ax2.contour(
385 np.log10(sample_x),
386 np.log10(sample_y),
387 logSNR,
388 print_logLevels,
389 **contour_kwargs
390 )
392 dists_min = cosmo.luminosity_distance(ylabel_min).to("Gpc")
393 dists_min = np.ceil(np.log10(dists_min.value))
394 dists_max = cosmo.luminosity_distance(ylabel_max).to("Gpc")
395 dists_max = np.ceil(np.log10(dists_max.value))
396 dists = np.arange(dists_min, dists_max)
397 dists = 10 ** dists * u.Gpc
399 distticks = [z_at_value(cosmo.luminosity_distance, dist) for dist in dists]
400 # Set other side y-axis for lookback time scalings
401 ax2.set_yticks(np.log10(distticks))
402 # ax2.set_yticklabels(['%f' %dist for dist in distticks],fontsize = axissize)
403 ax2.set_yticklabels(
404 [
405 r"$10^{%i}$" % np.log10(dist)
406 if np.abs(int(np.log10(dist))) > 1
407 else "{:g}".format(dist)
408 for dist in dists.value
409 ]
410 )
411 ax2.set_ylabel(r"$D_{L}$ [Gpc]")
413 # cbar = fig.colorbar(CS1,cax=cbar_ax,ax=(ax,ax2),pad=0.01,ticks=print_logLevels)
414 elif lb_axis:
415 if var_y != "z":
416 raise ValueError(
417 "Sorry, we can only plot lookback time when redshift is on the y axis."
418 )
419 # Set other side y-axis for lookback time scalings
420 ax2 = ax.twinx()
421 # Set axis scales based on what data sampling we used
422 if yaxis_type == "lin" and xaxis_type == "log":
423 ax2.contour(
424 np.log10(sample_x), sample_y, logSNR, print_logLevels, **contour_kwargs
425 )
426 elif yaxis_type == "log" and xaxis_type == "lin":
427 ax2.contour(
428 sample_x, np.log10(sample_y), logSNR, print_logLevels, **contour_kwargs
429 )
430 else:
431 ax2.contour(
432 np.log10(sample_x),
433 np.log10(sample_y),
434 logSNR,
435 print_logLevels,
436 **contour_kwargs
437 )
439 ages1 = np.array([13.5, 13, 10, 5, 1]) * u.Gyr
440 ages2 = np.array([500, 100, 10, 1]) * u.Myr
441 ages2 = ages2.to("Gyr")
442 ages = np.hstack((ages1.value, ages2.value))
443 ages = ages * u.Gyr
444 ageticks = [z_at_value(cosmo.age, age) for age in ages]
446 # Set axes limits
447 ax2.set_yticks(np.log10(ageticks))
448 ax2.set_yticklabels(["{:g}".format(age) for age in ages.value])
449 ax2.set_ylabel(r"$t_{\rm cosmic}$ [Gyr]")
450 ax2.yaxis.set_label_coords(1.2, 0.5)
452 if display_cbar:
453 if lb_axis or dl_axis:
454 fig.subplots_adjust(right=0.8)
455 cbar_ax = fig.add_axes([0.9, 0.15, 0.025, 0.7])
456 # Make colorbar
457 if cfill == False:
458 # Make colorbar
459 norm = colors.Normalize(vmin=logLevels_min, vmax=logLevels_max)
460 tick_levels = np.linspace(
461 float(logLevels_min), logLevels_max, len(print_logLevels)
462 )
463 cbar = mpl.colorbar.ColorbarBase(
464 cbar_ax,
465 ax=(ax, ax2),
466 pad=0.01,
467 cmap=CS1.cmap,
468 norm=norm,
469 boundaries=tick_levels,
470 ticks=tick_levels,
471 spacing="proportional",
472 )
473 else:
474 cbar = fig.colorbar(CS1, cax=cbar_ax, ax=(ax, ax2), pad=0.01)
475 else:
476 fig.subplots_adjust(right=0.8)
477 cbar_ax = fig.add_axes([0.82, 0.15, 0.025, 0.7])
478 if cfill == False:
479 # Make colorbar
480 norm = colors.Normalize(vmin=logLevels_min, vmax=logLevels_max)
481 tick_levels = np.linspace(
482 float(logLevels_min), logLevels_max, len(print_logLevels)
483 )
484 cbar = mpl.colorbar.ColorbarBase(
485 cbar_ax,
486 cmap=CS1.cmap,
487 norm=norm,
488 boundaries=tick_levels,
489 ticks=tick_levels,
490 spacing="proportional",
491 )
492 else:
493 # Make colorbar
494 cbar = fig.colorbar(CS1, cax=cbar_ax, ticks=print_logLevels)
496 cbar.set_label(r'SNR')
497 cbar.ax.set_yticklabels(
498 [
499 r"$10^{%i}$" % x if int(x) > 1 else r"$%i$" % (10 ** x)
500 for x in print_logLevels
501 ],
502 **yticklabels_kwargs
503 )
505 if display:
506 # fig.tight_layout()
507 fig.subplots_adjust(hspace=hspace, wspace=wspace)
508 plt.show()
510 if return_plt:
511 return fig, ax
514def Get_Axes_Labels(
515 ax,
516 var_axis,
517 var,
518 var_scale,
519 orig_labels,
520 line_val,
521 label_kwargs,
522 tick_label_kwargs,
523 line_kwargs,
524):
525 """Gives paper plot labels for given axis
527 Parameters
528 ----------
529 ax: object
530 The current axes object
531 var_axis: str
532 The axis to change labels and ticks, can either be 'y' or 'x'
533 var: str
534 The variable to label
535 orig_labels: list,np.ndarray
536 The original labels for the particular axis, may be updated depending on parameter
537 line_val: int,float
538 Value of line plotted on var_axis if not None. Assumed to be non-log10 value
539 label_kwargs: dict
540 The dictionary adjusting the particular axis' label kwargs
541 tick_label_kwargs: dict
542 The dictionary adjusting the particular axis' tick label kwargs
543 line_kwargs: dict
544 The dictionary associated with the line displayed on var_axis
546 """
548 # Set axes labels and whether log or linearly spaced
549 if var_axis not in ["y", "x"]:
550 raise ValueError("var_axis can only by x or y")
552 ax_dict = {}
554 if var == "M":
555 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
556 ax_dict[var_axis + "label"] = r"$M_{\mathrm{tot}}~[M_{\odot}]$"
557 ax_dict[var_axis + "ticklabels"] = [
558 r"$10^{%i}$" % x if int(x) > 1 else r"$%i$" % (10 ** x)
559 for x in np.log10(orig_labels)
560 ]
561 elif var == "q":
562 new_labels = orig_labels[::2]
563 ax_dict[var_axis + "ticks"] = new_labels
564 ax_dict[var_axis + "label"] = r"$\mathrm{Mass~Ratio}~q$"
565 ax_dict[var_axis + "ticklabels"] = [r"$%i$" % int(x) for x in new_labels]
566 elif var == "z":
567 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
568 ax_dict[var_axis + "label"] = r"$\mathrm{Redshift}~z$"
569 ax_dict[var_axis + "ticklabels"] = [
570 x if int(x) < 1 else int(x) for x in orig_labels
571 ]
572 elif var in ["chi1", "chi2"]:
573 new_labels = (
574 np.arange(round(min(orig_labels) * 10), round(max(orig_labels) * 10) + 1, 1)
575 / 10
576 )
577 new_labels = new_labels[::2]
578 ax_dict[var_axis + "ticks"] = new_labels
579 ax_dict[var_axis + "label"] = r"$\mathrm{Spin}~\chi_{i}$"
580 ax_dict[var_axis + "ticklabels"] = [r"$%.1f$" % x for x in new_labels]
581 elif var == "L":
582 # Proposed Value = 2.5Gm: L3 LISA
583 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
584 ax_dict[var_axis + "label"] = r"Arm Length [m]"
585 ax_dict[var_axis + "ticklabels"] = [
586 r"$10^{%i}$" % x if int(x) > 1 else r"$%i$" % (10 ** x)
587 for x in np.log10(orig_labels)
588 ]
589 elif var == "A_acc":
590 # Proposed Value = 3x10^{-15}: L3 LISA
591 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
592 ax_dict[var_axis + "label"] = r"$A_{\mathrm{acc}} [\mathrm{m~s^{-2}}]$"
593 ax_dict[var_axis + "ticklabels"] = [
594 r"$10^{%.0f}$" % x for x in np.log10(orig_labels)
595 ]
596 elif var == "A_IFO":
597 # Proposed Value = 10^{-12}: L3 LISA
598 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
599 ax_dict[var_axis + "label"] = r"$A_{\mathrm{IFO}}$ [m]"
600 ax_dict[var_axis + "ticklabels"] = [
601 r"$10^{%.0f}$" % x for x in np.log10(orig_labels)
602 ]
603 elif var == "f_acc_break_low":
604 # Proposed Value = 0.4mHz: L3 LISA
605 scale = 10 ** round(np.log10(min(orig_labels)))
606 new_labels = (
607 np.arange(
608 round(min(orig_labels) / scale), round(max(orig_labels) / scale) + 1, 1
609 )
610 * scale
611 )
612 ax_dict[var_axis + "ticks"] = new_labels
613 ax_dict[var_axis + "label"] = r"$f_{\mathrm{acc,low}}$ [mHz]"
614 ax_dict[var_axis + "ticklabels"] = [r"$%.1f$" % x for x in new_labels * 1e3]
615 elif var == "f_acc_break_high":
616 # Proposed Value = 8mHz: L3 LISA
617 scale = 10 ** round(np.log10(min(orig_labels)))
618 new_labels = (
619 np.arange(
620 round(min(orig_labels) / scale), round(max(orig_labels) / scale) + 1, 1
621 )
622 * scale
623 )
624 ax_dict[var_axis + "ticks"] = new_labels
625 ax_dict[var_axis + "label"] = r"$f_{\mathrm{acc,high}}$ [mHz]"
626 ax_dict[var_axis + "ticklabels"] = [r"$%.1f$" % x for x in new_labels * 1e3]
627 elif var == "f_IFO_break":
628 # Proposed Value = 2mHz: L3 LISA
629 scale = 10 ** round(np.log10(min(orig_labels)))
630 new_labels = (
631 np.arange(
632 round(min(orig_labels) / scale), round(max(orig_labels) / scale) + 1, 1
633 )
634 * scale
635 )
636 ax_dict[var_axis + "ticks"] = new_labels
637 ax_dict[var_axis + "label"] = r"$f_{\mathrm{IFO,break}}$ [mHz]"
638 ax_dict[var_axis + "ticklabels"] = [r"$%.1f$" % x for x in new_labels * 1e3]
639 elif var == "n_p":
640 sample_range = max(orig_labels) - min(orig_labels)
641 sample_rate = max(2, int(sample_range / 10))
642 new_labels = orig_labels[::sample_rate]
643 ax_dict[var_axis + "ticks"] = new_labels
644 ax_dict[var_axis + "label"] = r"$\mathrm{Number~of~Pulsars}$"
645 ax_dict[var_axis + "ticklabels"] = [r"$%i$" % int(x) for x in new_labels]
646 elif var == "cadence":
647 new_labels = np.arange(round(min(orig_labels)), round(max(orig_labels)) + 1, 5)
648 ax_dict[var_axis + "ticks"] = new_labels
649 ax_dict[
650 var_axis + "label"
651 ] = r"$\mathrm{Observation~Cadence}$ $[\mathrm{yr}^{-1}]$"
652 ax_dict[var_axis + "ticklabels"] = [r"$%i$" % int(x) for x in new_labels]
653 elif var == "sigma":
654 scale = 10 ** round(np.log10(min(orig_labels)))
655 new_labels = (
656 np.arange(
657 round(min(orig_labels) / scale), round(max(orig_labels) / scale) + 1, 1
658 )
659 * scale
660 )
661 ax_dict[var_axis + "ticks"] = new_labels
662 ax_dict[var_axis + "label"] = r"TOA Error RMS [ns]"
663 ax_dict[var_axis + "ticklabels"] = [r"$%.0f$" % x for x in new_labels * 1e9]
664 elif var == "T_obs":
665 new_labels = orig_labels[::2]
666 ax_dict[var_axis + "ticks"] = new_labels
667 ax_dict[var_axis + "label"] = r"${\rm T_{obs}}$ [yr]"
668 ax_dict[var_axis + "ticklabels"] = [r"$%i$" % int(x) for x in new_labels]
669 elif var == "Infrastructure Length":
670 # Proposed Value = 3995: aLIGO, Voyager
671 # Proposed Value = 40000: CE1
672 if var_scale == "log":
673 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
674 ax_dict[var_axis + "label"] = r"Infrastructure Length [m]"
675 ax_dict[var_axis + "ticklabels"] = [
676 r"$10^{%.0f}$" % y if abs(int(y)) > 1 else r"$%.1f$" % (10 ** y)
677 for y in np.log10(orig_labels)
678 ]
679 elif var_scale == "lin":
680 ax_dict[var_axis + "ticks"] = orig_labels
681 ax_dict[var_axis + "label"] = r"Infrastructure Length [km]"
682 ax_dict[var_axis + "ticklabels"] = [
683 r"$%.1f$" % (x / 1e3) for x in orig_labels
684 ]
685 elif var == "Laser Power":
686 # Proposed Value = 125: aLIGO
687 # Proposed Value = 145: Voyager
688 # Proposed Value = 150: CE1
689 if var_scale == "log":
690 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
691 ax_dict[var_axis + "label"] = r"Laser Power [W]"
692 ax_dict[var_axis + "ticklabels"] = [
693 r"$10^{%.0f}$" % x if abs(int(x)) > 1 else r"$%.1f$" % (10 ** x)
694 for x in np.log10(orig_labels)
695 ]
696 elif var_scale == "lin":
697 ax_dict[var_axis + "ticks"] = orig_labels
698 ax_dict[var_axis + "label"] = r"Laser Power [W]"
699 ax_dict[var_axis + "ticklabels"] = [r"$%.1f$" % x for x in orig_labels]
700 elif var == "Seismic Gamma":
701 # Proposed Value = 0.8: aLIGO, Voyager, CE1
702 if var_scale == "log":
703 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
704 ax_dict[var_axis + "label"] = r"Seismic Gamma"
705 ax_dict[var_axis + "ticklabels"] = [
706 r"$10^{%.0f}$" % y if abs(int(y)) > 1 else r"$%.1f$" % (10 ** y)
707 for y in np.log10(orig_labels)
708 ]
709 elif var_scale == "lin":
710 ax_dict[var_axis + "ticks"] = orig_labels
711 ax_dict[var_axis + "label"] = r"Seismic Gamma"
712 ax_dict[var_axis + "ticklabels"] = [r"$%.1f$" % y for y in orig_labels]
713 elif var == "Materials Substrate Temp":
714 # Proposed Value = 295: aLIGO, CE1
715 # Proposed Value = 123: Voyager
716 if var_scale == "lin":
717 ax_dict[var_axis + "ticks"] = orig_labels
718 ax_dict[var_axis + "label"] = r"Mirror Substrate Temp [K]"
719 ax_dict[var_axis + "ticklabels"] = [
720 r"$%.1f \times 10^{%i}$" % (x / 10 ** int(np.log10(x)), np.log10(x))
721 if np.abs(int(np.log10(x))) > 1
722 else "{:g}".format(x)
723 for x in orig_labels
724 ]
725 elif var_scale == "log":
726 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
727 ax_dict[var_axis + "label"] = r"Mirror Substrate Temp [K]"
728 ax_dict[var_axis + "ticklabels"] = [
729 r"$10^{%.0f}$" % y if abs(int(y)) > 1 else r"$%.1f$" % (10 ** y)
730 for y in np.log10(orig_labels)
731 ]
732 else:
733 if var_scale == "lin":
734 ax_dict[var_axis + "ticks"] = orig_labels
735 ax_dict[var_axis + "label"] = str(var)
736 ax_dict[var_axis + "ticklabels"] = [
737 r"$%.1f \times 10^{%i}$" % (x / 10 ** int(np.log10(x)), np.log10(x))
738 if np.abs(int(np.log10(x))) > 1
739 else "{:g}".format(x)
740 for x in orig_labels
741 ]
742 elif var_scale == "log":
743 ax_dict[var_axis + "ticks"] = np.log10(orig_labels)
744 ax_dict[var_axis + "label"] = str(var)
745 ax_dict[var_axis + "ticklabels"] = [
746 r"$10^{%.0f}$" % y if abs(int(y)) > 1 else r"$%.1f$" % (10 ** y)
747 for y in np.log10(orig_labels)
748 ]
749 if line_val is not None:
750 if "linestyle" not in line_kwargs.keys():
751 line_kwargs["linestyle"] = "--"
752 if "color" not in line_kwargs.keys():
753 line_kwargs["color"] = "k"
754 if "label" not in line_kwargs.keys():
755 line_kwargs["label"] = "Proposed Value"
757 if var_scale == "log":
758 if var_axis == "y":
759 ax.axhline(y=np.log10(line_val), **line_kwargs)
760 elif var_axis == "x":
761 ax.axvline(x=np.log10(line_val), **line_kwargs)
762 elif var_scale == "lin":
763 if var_axis == "y":
764 ax.axhline(y=line_val, **line_kwargs)
765 elif var_axis == "x":
766 ax.axvline(x=line_val, **line_kwargs)
768 ax.update(ax_dict)
769 if label_kwargs:
770 if var_axis == "y":
771 ax.set_ylabel(ax.get_ylabel(), **label_kwargs)
772 elif var_axis == "x":
773 ax.set_xlabel(ax.get_xlabel(), **label_kwargs)
775 if tick_label_kwargs:
776 if var_axis == "y":
777 ax.set_yticklabels(ax.get_yticklabels(), **tick_label_kwargs)
778 elif var_axis == "x":
779 ax.set_xticklabels(ax.get_xticklabels(), **tick_label_kwargs)