Repository: ARM-DOE/ACT

Issue:
Subpanel plots greater then index 2 seems to fail.
When plotting a suplot of size (2, 3) I receive this error:
```
File ~\dev\ACT\act\plotting\timeseriesdisplay.py:608, in TimeSeriesDisplay.plot(self, field, dsname, subplot_index, cmap, set_title, add_nan, day_night_background, invert_y_axis, abs_limits, time_rng, y_rng, use_var_for_y, set_shading, assessment_overplot, overplot_marker, overplot_behind, overplot_markersize, assessment_overplot_category, assessment_overplot_category_color, force_line_plot, labels, cbar_label, cbar_h_adjust, secondary_y, y_axis_flag_meanings, colorbar_labels, **kwargs)
    605     else:
    606         self.time_rng = [xdata.min().values, xdata.max().values]
--> 608 self.set_xrng(self.time_rng, subplot_index)
    610 # Set Y Limit
    611 if y_rng is not None:

File ~\dev\ACT\act\plotting\timeseriesdisplay.py:224, in TimeSeriesDisplay.set_xrng(self, xrng, subplot_index)
    222 warnings.filterwarnings('ignore', category=UserWarning)
    223 self.axes[subplot_index].set_xlim(xrng)
--> 224 self.xrng[subplot_index, 0] = np.array(xrng[0], dtype='datetime64[D]')
    225 self.xrng[subplot_index, 1] = np.array(xrng[1], dtype='datetime64[D]')

IndexError: index 2 is out of bounds for axis 0 with size 2
```


Discussion:
End goal plot layout:
![Screenshot (243)](https://user-images.githubusercontent.com/19153455/192602751-e48c0968-d856-4ea1-8030-4cbee3dc285e.png)


Resolving patch:
diff --git a/act/plotting/timeseriesdisplay.py b/act/plotting/timeseriesdisplay.py
--- a/act/plotting/timeseriesdisplay.py
+++ b/act/plotting/timeseriesdisplay.py
@@ -4,17 +4,17 @@
 """
 
 import datetime as dt
+import textwrap
 import warnings
 from copy import deepcopy
 from re import search, search as re_search
-import textwrap
 
+import matplotlib as mpl
 import matplotlib.dates as mdates
 import matplotlib.pyplot as plt
 import numpy as np
 import pandas as pd
 from matplotlib import colors as mplcolors
-import matplotlib as mpl
 from mpl_toolkits.axes_grid1 import make_axes_locatable
 from scipy.interpolate import NearestNDInterpolator
 
@@ -213,16 +213,18 @@ def set_xrng(self, xrng, subplot_index=(0,)):
         if self.axes is None:
             raise RuntimeError('set_xrng requires the plot to be displayed.')
 
-        if not hasattr(self, 'xrng') and len(self.axes.shape) == 2:
-            self.xrng = np.zeros((self.axes.shape[0], self.axes.shape[1], 2), dtype='datetime64[D]')
-        elif not hasattr(self, 'xrng') and len(self.axes.shape) == 1:
-            self.xrng = np.zeros((self.axes.shape[0], 2), dtype='datetime64[D]')
+        self.axes[subplot_index].set_xlim(xrng)
 
-        with warnings.catch_warnings():
-            warnings.filterwarnings('ignore', category=UserWarning)
-            self.axes[subplot_index].set_xlim(xrng)
-            self.xrng[subplot_index, 0] = np.array(xrng[0], dtype='datetime64[D]')
-            self.xrng[subplot_index, 1] = np.array(xrng[1], dtype='datetime64[D]')
+        # Make sure that the xrng value is a numpy array not pandas
+        if isinstance(xrng[0], pd.Timestamp):
+            xrng = [x.to_numpy() for x in xrng if isinstance(x, pd.Timestamp)]
+
+        if len(subplot_index) < 2:
+            self.xrng[subplot_index, 0] = xrng[0].astype('datetime64[D]').astype(float)
+            self.xrng[subplot_index, 1] = xrng[1].astype('datetime64[D]').astype(float)
+        else:
+            self.xrng[subplot_index][0] = xrng[0].astype('datetime64[D]').astype(float)
+            self.xrng[subplot_index][1] = xrng[1].astype('datetime64[D]').astype(float)
 
     def set_yrng(self, yrng, subplot_index=(0,)):
         """
@@ -248,7 +250,10 @@ def set_yrng(self, yrng, subplot_index=(0,)):
             yrng[1] = yrng[1] + 1
 
         self.axes[subplot_index].set_ylim(yrng)
-        self.yrng[subplot_index, :] = yrng
+        try:
+            self.yrng[subplot_index, :] = yrng
+        except IndexError:
+            self.yrng[subplot_index] = yrng
 
     def plot(
         self,
@@ -653,10 +658,7 @@ def plot(
         if len(subplot_index) == 1:
             days = self.xrng[subplot_index, 1] - self.xrng[subplot_index, 0]
         else:
-            days = (
-                self.xrng[subplot_index[0], subplot_index[1], 1]
-                - self.xrng[subplot_index[0], subplot_index[1], 0]
-            )
+            days = self.xrng[subplot_index][1] - self.xrng[subplot_index][0]
 
         myFmt = common.get_date_format(days)
         ax.xaxis.set_major_formatter(myFmt)
@@ -677,15 +679,21 @@ def plot(
 
             if colorbar_labels is not None:
                 cbar_title = None
-                cbar = self.add_colorbar(mesh, title=cbar_title, subplot_index=subplot_index,
-                                         values=flag_values, pad=cbar_h_adjust)
+                cbar = self.add_colorbar(
+                    mesh,
+                    title=cbar_title,
+                    subplot_index=subplot_index,
+                    values=flag_values,
+                    pad=cbar_h_adjust,
+                )
                 cbar.set_ticks(flag_values)
                 cbar.set_ticklabels(flag_meanings)
                 cbar.ax.tick_params(labelsize=10)
 
             else:
-                self.add_colorbar(mesh, title=cbar_title, subplot_index=subplot_index,
-                                  pad=cbar_h_adjust)
+                self.add_colorbar(
+                    mesh, title=cbar_title, subplot_index=subplot_index, pad=cbar_h_adjust
+                )
 
         return ax
 
@@ -1138,7 +1146,7 @@ def plot_time_height_xsection_from_1d_data(
             self.axes[subplot_index].set_ylabel(ytitle)
 
         # Set X Limit - We want the same time axes for all subplots
-        time_rng = [x_times[-1], x_times[0]]
+        time_rng = [x_times[0], x_times[-1]]
 
         self.set_xrng(time_rng, subplot_index)
 
diff --git a/examples/plot_multiple_column.py b/examples/plot_multiple_column.py
new file mode 100644
--- /dev/null
+++ b/examples/plot_multiple_column.py
@@ -0,0 +1,28 @@
+"""
+Plot a timeseries of sounding data
+----------------------------------------------------
+
+This is a simple example for how to plot multiple columns
+in a TimeseriesDisplay.
+
+Author: Maxwell Grover
+"""
+
+from matplotlib import pyplot as plt
+
+import act
+
+files = act.tests.sample_files.EXAMPLE_MET_WILDCARD
+met = act.io.armfiles.read_netcdf(files)
+
+
+# Plot data
+display = act.plotting.TimeSeriesDisplay(met)
+display.add_subplots((3, 2), figsize=(15, 10))
+display.plot('temp_mean', color='tab:red', subplot_index=(0, 0))
+display.plot('rh_mean', color='tab:green', subplot_index=(1, 0))
+display.plot('wdir_vec_mean', subplot_index=(2, 0))
+display.plot('temp_std', color='tab:red', subplot_index=(0, 1))
+display.plot('rh_std', color='tab:green', subplot_index=(1, 1))
+display.plot('wdir_vec_std', subplot_index=(2, 1))
+plt.show()


Test patch: