diff --git a/b_asic/gui_utils/mpl_window.py b/b_asic/gui_utils/mpl_window.py
index 7251ac38fd2e1a84e5f2f217211e39fac6703557..eec93e2c35cf1eecf16c2e197c2808ed1f6281ef 100644
--- a/b_asic/gui_utils/mpl_window.py
+++ b/b_asic/gui_utils/mpl_window.py
@@ -12,7 +12,7 @@ class MPLWindow(QDialog):
     Dialog for plotting Matplotlib things.
     """
 
-    def __init__(self, title: str = "B-ASIC"):
+    def __init__(self, title: str = "B-ASIC", subplots=(1, 1)):
         super().__init__()
         self.setWindowFlags(
             Qt.WindowTitleHint
@@ -26,7 +26,7 @@ class MPLWindow(QDialog):
         self.setLayout(self._dialog_layout)
 
         self._plot_fig = Figure(figsize=(5, 4), layout="compressed")
-        self._plot_axes = self._plot_fig.add_subplot(111)
+        self._plot_axes = self._plot_fig.subplots(*subplots)
 
         self._plot_canvas = FigureCanvas(self._plot_fig)
         self._toolbar = NavigationToolbar(self._plot_canvas, self)
diff --git a/b_asic/resources.py b/b_asic/resources.py
index fedad2d90c5a007cc9aa386ea6a7758baf9f7d94..08668aecdf7ed889eadbcb79c80f56d8601dee21 100644
--- a/b_asic/resources.py
+++ b/b_asic/resources.py
@@ -1458,6 +1458,43 @@ class ProcessCollection:
 
         return dict(sorted(Counter(accesses).items()))
 
+    def show_port_accesses(self, title: str = ""):
+        """
+        Show read, write, and total accesses.
+
+        Parameters
+        ----------
+        title : str
+            Figure title.
+        """
+        fig, axes = plt.subplots(3, 1)
+        self.plot_port_accesses(axes)
+        if title:
+            fig.suptitle(title)
+        fig.show()  # type: ignore
+
+    def plot_port_accesses(self, axes):
+        """
+        Plot read, write, and total accesses.
+
+        This is plot as bar graphs.
+
+        Parameters
+        ----------
+        axes : list of three :class:`matplotlib.axes.Axes`
+            Three Axes to plot in.
+        """
+        axes[0].bar(*zip(*self.read_port_accesses().items()))
+        axes[0].set_title("Read port accesses")
+        axes[1].bar(*zip(*self.write_port_accesses().items()))
+        axes[1].set_title("Write port accesses")
+        axes[2].bar(*zip(*self.total_port_accesses().items()))
+        axes[2].set_title("Total port accesses")
+        for ax in axes:
+            ax.xaxis.set_major_locator(MaxNLocator(integer=True, min_n_ticks=1))
+            ax.yaxis.set_major_locator(MaxNLocator(integer=True, min_n_ticks=1))
+            ax.set_xlim(-0.5, self.schedule_time - 0.5)
+
     def from_name(self, name: str):
         """
         Get a :class:`~b_asic.process.Process` from its name.
diff --git a/b_asic/scheduler_gui/axes_item.py b/b_asic/scheduler_gui/axes_item.py
index 43d56c9dfb74a4c9399a8584a59f88c3834f3efd..65520ea6a81703da518800fdc1883a8b1ba3b2eb 100644
--- a/b_asic/scheduler_gui/axes_item.py
+++ b/b_asic/scheduler_gui/axes_item.py
@@ -30,8 +30,8 @@ class AxesItem(QGraphicsItemGroup):
 
     Parameters
     ----------
-    width
-    height
+    width : int
+    height : float
     width_indent : float, default: {SCHEDULE_INDENT}
     height_indent : float, default: {SCHEDULE_INDENT}
     width_padding : float, default: 0.6
diff --git a/b_asic/scheduler_gui/compile.py b/b_asic/scheduler_gui/compile.py
index 8095aa4c361cddf6bee7821102e5dcc79b9af3dd..2d9be5282811344e6a95548244e85a9195a1dfde 100644
--- a/b_asic/scheduler_gui/compile.py
+++ b/b_asic/scheduler_gui/compile.py
@@ -2,7 +2,7 @@
 """
 B-ASIC Scheduler-gui Resource and Form Compiler Module.
 
-Compiles Qt5 resource and form files. Requires PySide2 or PyQt5 to be installed.
+Compile Qt5 resource and form files. Requires PySide2 or PyQt5 to be installed.
 If no arguments is given, the compiler search for and compiles all form (.ui)
 files.
 """
@@ -37,8 +37,9 @@ def _check_filenames(*filenames: str) -> None:
 
 def _check_qt_version() -> None:
     """
-    Check if PySide2, PyQt5, PySide6, or PyQt6 is installed, otherwise raise
-    AssertionError exception.
+    Check if PySide2, PyQt5, PySide6, or PyQt6 is installed.
+
+    Otherwise, raise AssertionError exception.
     """
     assert (
         uic.PYSIDE2 or uic.PYQT5 or uic.PYSIDE6 or uic.PYQT6
@@ -46,8 +47,15 @@ def _check_qt_version() -> None:
 
 
 def replace_qt_bindings(filename: str) -> None:
-    """Replaces qt-binding API in *filename* from PySide2/6 or PyQt5/6 to qtpy."""
-    with open(f"{filename}", "r") as file:
+    """
+    Replace qt-binding API in *filename* from PySide2/6 or PyQt5/6 to qtpy.
+
+    Parameters
+    ----------
+    filename : str
+        The name of the file to replace bindings in.
+    """
+    with open(f"{filename}") as file:
         filedata = file.read()
         filedata = filedata.replace("from PyQt5", "from qtpy")
         filedata = filedata.replace("from PySide2", "from qtpy")
@@ -59,8 +67,15 @@ def replace_qt_bindings(filename: str) -> None:
 
 def compile_rc(*filenames: str) -> None:
     """
-    Compile resource file(s) given by *filenames*. If no arguments are given,
-    the compiler will search for resource (.qrc) files and compile accordingly.
+    Compile resource file(s) given by *filenames*.
+
+    If no arguments are given, the compiler will search for resource (.qrc) files and
+    compile accordingly.
+
+    Parameters
+    ----------
+    *filenames : str
+        One or more file names.
     """
     _check_qt_version()
 
@@ -127,8 +142,15 @@ def compile_rc(*filenames: str) -> None:
 
 def compile_ui(*filenames: str) -> None:
     """
-    Compile form file(s) given by *filenames*. If no arguments are given, the
-    compiler will search for form (.ui) files and compile accordingly.
+    Compile form file(s) given by *filenames*.
+
+    If no arguments are given, the compiler will search for form (.ui) files and
+    compile accordingly.
+
+    Parameters
+    ----------
+    *filenames : str
+        One or more file names.
     """
     _check_qt_version()
 
@@ -228,6 +250,8 @@ def compile_ui(*filenames: str) -> None:
 
 def compile_all() -> None:
     """
+    Compile all .qrc and .ui files.
+
     The compiler will search for resource (.qrc) files and form (.ui) files
     and compile accordingly.
     """
@@ -246,37 +270,26 @@ if __name__ == "__main__":
         "-v", "--version", action="version", version=f"%(prog)s v{version}"
     )
 
-    if sys.version_info >= (3, 8):
-        parser.add_argument(
-            "--ui",
-            metavar="<file>",
-            action="extend",
-            nargs="*",
-            help=(
-                "compile form file(s) if <file> is given, otherwise search\n"
-                "for all form (*.ui) files and compile them all (default)"
-            ),
-        )
-        parser.add_argument(
-            "--rc",
-            metavar="<file>",
-            action="extend",
-            nargs="*",
-            help=(
-                "compile resource file(s) if <file> is given, otherwise\n"
-                "search for all resource (*.ui) files and compile them all"
-            ),
-        )
-    else:
-        parser.add_argument(
-            "--ui", metavar="<file>", action="append", help="compile form file"
-        )
-        parser.add_argument(
-            "--rc",
-            metavar="<file>",
-            action="append",
-            help="compile resource file",
-        )
+    parser.add_argument(
+        "--ui",
+        metavar="<file>",
+        action="extend",
+        nargs="*",
+        help=(
+            "compile form file(s) if <file> is given, otherwise search\n"
+            "for all form (*.ui) files and compile them all (default)"
+        ),
+    )
+    parser.add_argument(
+        "--rc",
+        metavar="<file>",
+        action="extend",
+        nargs="*",
+        help=(
+            "compile resource file(s) if <file> is given, otherwise\n"
+            "search for all resource (*.ui) files and compile them all"
+        ),
+    )
 
     parser.add_argument(
         "--all",
diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py
index c82466c92b5e0b34a7811bf8ff00fd9eb463dcfa..5f729f36587a9e2ac015b93d295fd9cecf63bf2c 100644
--- a/b_asic/scheduler_gui/main_window.py
+++ b/b_asic/scheduler_gui/main_window.py
@@ -164,6 +164,9 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         self.action_view_variables.triggered.connect(
             self._show_execution_times_for_variables
         )
+        # self.action_view_port_accesses.triggered.connect(
+        #     self._show_ports_accesses_for_storage
+        # )
         self.actionZoom_to_fit.setIcon(get_icon('zoom-to-fit'))
         self.actionZoom_to_fit.triggered.connect(self._zoom_to_fit)
         self.actionToggle_full_screen.setIcon(get_icon('full-screen'))
@@ -847,6 +850,16 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
         )
         self._execution_time_for_variables.show()
 
+    def _show_ports_accesses_for_storage(self):
+        self._ports_accesses_for_storage = MPLWindow(
+            "Port accesses for storage", subplots=(3, 1)
+        )
+        mem_vars = self._schedule.get_memory_variables()
+        _, mem_vars = mem_vars.split_on_length()
+
+        mem_vars.plot_port_accesses(self._ports_accesses_for_storage.axes)
+        self._ports_accesses_for_storage.show()
+
     def _update_recent_file_list(self):
         settings = QSettings()
 
diff --git a/b_asic/scheduler_gui/timeline_item.py b/b_asic/scheduler_gui/timeline_item.py
index d2d82d399d7f50fdddcbb9023370632dd8af92c2..048a92a025645a9f34319d71ff0673245df0f092 100644
--- a/b_asic/scheduler_gui/timeline_item.py
+++ b/b_asic/scheduler_gui/timeline_item.py
@@ -1,5 +1,4 @@
 #!/usr/bin/env python3
-# -*- coding: utf-8 -*-
 """
 B-ASIC Scheduler-GUI Timeline Item Module.
 
@@ -78,7 +77,14 @@ class TimelineItem(QGraphicsLineItem):
     #     return self._delta_time_label
 
     def set_text(self, number: int) -> None:
-        """Set the label text to *number*."""
+        """
+        Set the label text to *number*.
+
+        Parameters
+        ----------
+        number : int
+            The label number.
+        """
         # self.prepareGeometryChange()
         self._delta_time_label.setPlainText(f"( {number:+} )")
         self._delta_time_label.setX(
@@ -106,6 +112,14 @@ class TimelineItem(QGraphicsLineItem):
         self._delta_time_label.hide()
 
     def set_text_scale(self, scale: float) -> None:
+        """
+        Set the text scale.
+
+        Parameters
+        ----------
+        scale : float
+            The text scale.
+        """
         self._delta_time_label.setScale(scale)
 
     @property
diff --git a/b_asic/simulation.py b/b_asic/simulation.py
index 2a6e7b6e81c2569aec7aa1a63ea891b05e060720..31f25910432b1be5ea7cee5aec2a98547bd1375b 100644
--- a/b_asic/simulation.py
+++ b/b_asic/simulation.py
@@ -106,6 +106,10 @@ class Simulation:
     def set_inputs(self, input_providers: Sequence[Optional[InputProvider]]) -> None:
         """
         Set the input functions used to get values for the inputs to the internal SFG.
+
+        Parameters
+        ----------
+        input_providers : array of list, callable, or number
         """
         if len(input_providers) != self._sfg.input_count:
             raise ValueError(
@@ -122,7 +126,14 @@ class Simulation:
         bits_override: Optional[int] = None,
         quantize: bool = True,
     ) -> Sequence[Num]:
-        """Run one iteration of the simulation and return the resulting output values.
+        """
+        Run one iteration of the simulation and return the resulting output values.
+
+        Parameters
+        ----------
+        save_results : bool, default: True
+        bits_override : int, optional
+        quantize : bool, default: True
         """
         return self.run_for(1, save_results, bits_override, quantize)
 
@@ -134,10 +145,19 @@ class Simulation:
         quantize: bool = True,
     ) -> Sequence[Num]:
         """
-        Run the simulation a given number of iterations.
+        Run the simulation until the iteration number.
 
         Will run until the number of iterations is greater than or equal to the given
-        iteration and return the output values of the last iteration.
+        iteration and return the output values of the last iteration. The number of
+        iterations actually simulated depends on the current state of the Simulation.
+
+        Parameters
+        ----------
+        iteration : int
+            Iteration number to stop the simulation at.
+        save_results : bool, default: True
+        bits_override : int, optional
+        quantize : bool, default: True
         """
         result: Sequence[Num] = []
         while self._iteration < iteration:
@@ -171,6 +191,14 @@ class Simulation:
         Run a given number of iterations of the simulation.
 
         Return the output values of the last iteration.
+
+        Parameters
+        ----------
+        iterations : int
+            Number of iterations to simulate.
+        save_results : bool, default: True
+        bits_override : int, optional
+        quantize : bool, default: True
         """
         return self.run_until(
             self._iteration + iterations, save_results, bits_override, quantize
@@ -186,6 +214,12 @@ class Simulation:
         Run the simulation until the end of its input arrays.
 
         Return the output values of the last iteration.
+
+        Parameters
+        ----------
+        save_results : bool, default: True
+        bits_override : int, optional
+        quantize : bool, default: True
         """
         if self._input_length is None:
             raise IndexError("Tried to run unlimited simulation")
@@ -199,7 +233,7 @@ class Simulation:
     @property
     def results(self) -> ResultArrayMap:
         """
-        Get a mapping from result keys to numpy arrays containing all results.
+        A mapping from result keys to numpy arrays containing all results.
 
         This includes intermediate values, calculated for each iteration up until now
         that was run with *save_results* enabled.