diff --git a/CHANGELOG.md b/CHANGELOG.md index 50c39bc..2e9cc44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # PySEP Changelog +## Version 0.7.1 + +- #169: Response removal exception broadened +- #170: Allow more customization of RecSec + ## Version 0.7.0 - #148: New RecSec features `--remove_locations` and `--export_traces` diff --git a/pyproject.toml b/pyproject.toml index 937569e..8de4c16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pysep-adjtomo" -version = "0.7.0" +version = "0.7.1" description = "Python Seismogram Extraction and Processing" readme = "README.md" requires-python = ">=3.8" diff --git a/pysep/recsec.py b/pysep/recsec.py index 13c8daa..1644310 100755 --- a/pysep/recsec.py +++ b/pysep/recsec.py @@ -149,7 +149,7 @@ def __init__(self, # Figure generation control max_traces_per_rs=None, xlim_s=None, y_axis_spacing=1, y_label_loc="default", tmarks=None, - figsize=(9, 11), show=True, save="./record_section.png", + figsize=(9, 11), dpi=100, show=True, save="./record_section.png", export_traces=False, # Miscellaneous parameters overwrite=True, log_level="DEBUG", **kwargs): @@ -441,6 +441,11 @@ def __init__(self, vertical lines at 0s, 100s and 200s :type figsize: tuple of float :param figsize: size the of the figure, passed into plt.subplots() + :type dpi: int + :param dpi: resolution of the figure, passed into plt.subplots() + Defaults to 100. Higher DPI will result in larger file size. + If you want to save a high-resolution figure, set this to 300 or + higher. :type show: bool :param show: show the figure as a graphical output :type save: str @@ -631,6 +636,7 @@ def __init__(self, self.y_label_loc = y_label_loc self.tmarks = tmarks self.figsize = figsize + self.dpi = int(dpi) self.show = bool(show) self.save = save @@ -1876,6 +1882,9 @@ def plot(self, subset=None, page_num=None, **kwargs): name and title to differentiate different pages of the same record section """ + # This will set the color of the figure outside of the axes + bg_color = self.kwargs.get("bg_color", "white") + if subset is None: start, stop = 0, None # None will allow full list traversal nwav = len(self.sorted_idx) @@ -1899,7 +1908,8 @@ def plot(self, subset=None, page_num=None, **kwargs): logger.debug( f"\nIDX\tY\t\tID\tDIST\tAZ\tBAZ\t{DLT}T{SYNSHIFT}\tTOFFSET\tYABSMAX" ) - self.f, self.ax = plt.subplots(figsize=self.figsize) + self.f, self.ax = plt.subplots(figsize=self.figsize, dpi=self.dpi, + facecolor=bg_color) log_str = "\n" # Allow choosing observed or synthetic data, defaults to observed @@ -2416,7 +2426,7 @@ def _set_y_axis_text_labels(self, start=0, stop=-1, loc="y_axis"): self.ax.set_yticks(self.y_axis[start:stop]) self.ax.set_yticklabels(y_tick_labels) plt.text(-.01, .99, y_fmt, ha="right", va="top", - transform=self.ax.transAxes, fontsize=fontsize) + transform=self.ax.transAxes, fontsize=fontsize, c=c) # Set the y-axis labels to the right side of the right figure border elif loc == "y_axis_right": self.ax.set_yticks(self.y_axis[start:stop]) @@ -2424,7 +2434,7 @@ def _set_y_axis_text_labels(self, start=0, stop=-1, loc="y_axis"): self.ax.yaxis.tick_right() self.ax.yaxis.set_label_position("right") plt.text(1.01, .99, y_fmt, ha="left", va="top", - transform=self.ax.transAxes, fontsize=fontsize) + transform=self.ax.transAxes, fontsize=fontsize, c=c) # Option 2: Plotting labels as text objects, separate from y-axis labels else: # 2a: Set the y-axis labels inside the figure border (xmin or xmax) @@ -2435,14 +2445,15 @@ def _set_y_axis_text_labels(self, start=0, stop=-1, loc="y_axis"): func = min x_val = func(self.stats.xmin) plt.text(.01, .99, y_fmt, ha=ha, va=va, - transform=self.ax.transAxes, fontsize=fontsize) + transform=self.ax.transAxes, fontsize=fontsize, c=c) elif loc == "x_max": ha = "right" va = "top" func = max x_val = func(self.stats.xmax) plt.text(.99, .99, y_fmt, ha=ha, va=va, - transform=self.ax.transAxes, fontsize=fontsize) + transform=self.ax.transAxes, fontsize=fontsize, + c=c) # 2b: Set the y-axis labels outside figure border, co-existing with # y-labels showing distance or azimuth elif loc == "y_axis_abs": @@ -2451,14 +2462,14 @@ def _set_y_axis_text_labels(self, start=0, stop=-1, loc="y_axis"): func = min x_val = func(self.stats.xmin) plt.text(0, .99, y_fmt, ha=ha, va=va, - transform=self.ax.transAxes, fontsize=fontsize) + transform=self.ax.transAxes, fontsize=fontsize, c=c) elif loc == "y_axis_abs_right": ha = "left" va = "center" func = max x_val = func(self.stats.xmax) plt.text(1., .99, y_fmt, ha=ha, va=va, - transform=self.ax.transAxes, fontsize=fontsize) + transform=self.ax.transAxes, fontsize=fontsize, c=c) if self.xlim_s is not None: x_val = func([func(self.xlim_s), x_val]) diff --git a/pysep/utils/io.py b/pysep/utils/io.py index baa2c3b..b78031b 100644 --- a/pysep/utils/io.py +++ b/pysep/utils/io.py @@ -190,7 +190,8 @@ def read_events_plus(fid, format, **kwargs): events=[read_specfem3d_cmtsolution_cartesian(fid)] ) except Exception as e: - raise ValueError(f"unexpected source format {format} for {fid}") + raise ValueError(f"unexpected source format {format} for {fid}" + f"{e}") return cat diff --git a/pysep/utils/plot.py b/pysep/utils/plot.py index 71edf41..48f278a 100644 --- a/pysep/utils/plot.py +++ b/pysep/utils/plot.py @@ -286,12 +286,14 @@ def plot_source_receiver_map(inv, event, subset=None, save="./station_map.png", def set_plot_aesthetic( ax, ytick_fontsize=8., xtick_fontsize=12., tick_linewidth=1.5, - tick_length=5., tick_direction="in", xlabel_fontsize=10., - ylabel_fontsize=10., axis_linewidth=2., spine_zorder=8, spine_top=True, - spine_bot=True, spine_left=True, spine_right=True, title_fontsize=10., + tick_length=5., tick_color="k", tick_direction="in", + xlabel_fontsize=10., ylabel_fontsize=10., label_color="k", + axis_linewidth=2., + spine_zorder=8, spine_top=True, spine_bot=True, spine_left=True, + spine_right=True, spine_color="k", title_fontsize=10., title_color="k", xtick_minor=None, xtick_major=None, ytick_minor=None, ytick_major=None, xgrid_major=True, xgrid_minor=True, ygrid_major=True, ygrid_minor=True, - **kwargs): + frame_color=None, bg_color="w", **kwargs): """ Give a nice look to the output figure by creating thick borders on the axis, adjusting fontsize etc. All plot aesthetics should be placed here @@ -310,6 +312,8 @@ def set_plot_aesthetic( :type tick_direction: str :param tick_direction: 'in' for ticks pointing inwards, 'out' for ticks pointing outwards + :type tick_color: str + :param tick_color: color of the tick marks and their labels :type xlabel_fontsize: float :param xlabel_fontsize: font size for the X-axis main label (e.g., Time) :type ylabel_fontsize: float @@ -326,8 +330,12 @@ def set_plot_aesthetic( :param spine_left: toggle on/off the left axis border :type spine_right: bool :param spine_right: toggle on/off the right axis border + :type spine_color: str + :param spine_color: color of the axis frames/spines :type title_fontsize: float :param title_fontsize: font size of the main title at the top of the figure + :type title_color: str + :param title_color: color of the main title at the top of the figure :type xtick_minor: float :param xtick_minor: how often minor tick marks are drawn on X axis :type xtick_major: float @@ -344,17 +352,38 @@ def set_plot_aesthetic( :param ygrid_minor: turn on grid lines for each minor Y tick :type ygrid_major: bool :param ygrid_major: turn on grid lines for each minor Y tick + :type frame_color: str + :param frame_color: color of the frame around the figure, overwrites + `spine_color`, `tick_color`, `label_color`, and `title_color` + :type bg_color: str + :param bg_color: background color of the figure, defaults to white :rtype: matplotlib.axes._subplots.AxesSubplot :return: input axis with aesthetic changed """ + # Overwrite color so we don't have to set each one individually + if frame_color is not None: + tick_color = frame_color + spine_color = frame_color + label_color = frame_color + title_color = frame_color + ax.title.set_fontsize(title_fontsize) + ax.title.set_color(title_color) + ax.tick_params(axis="both", which="both", width=tick_linewidth, - direction=tick_direction, length=tick_length) + direction=tick_direction, length=tick_length, + color=tick_color, labelcolor=tick_color) ax.tick_params(axis="x", labelsize=xtick_fontsize) ax.tick_params(axis="y", labelsize=ytick_fontsize) + ax.xaxis.label.set_size(xlabel_fontsize) ax.yaxis.label.set_size(ylabel_fontsize) + ax.xaxis.label.set_color(label_color) + ax.yaxis.label.set_color(label_color) + # Set background color + ax.set_facecolor(bg_color) + # Thicken up the bounding axis lines for axis, flag in zip(["top", "bottom", "left", "right"], [spine_top, spine_bot, spine_left, spine_right]): @@ -363,6 +392,7 @@ def set_plot_aesthetic( flag = bool(flag.capitalize() == "True") ax.spines[axis].set_visible(flag) ax.spines[axis].set_linewidth(axis_linewidth) + ax.spines[axis].set_color(spine_color) # Set spines above azimuth bins for spine in ax.spines.values():