Repository: python-control/python-control

Issue:
Singular values plot not changing colors for list of systems
When the singular values plot is generated for a list of systems, the colors of the lines should be different for each system.  This doesn't seem to be happening.

Example:
```
import control as ct
sys1 = ct.rss(4, 2, 2, strictly_proper=True)
sys2 = ct.rss(4, 2, 2, strictly_proper=True)
ct.singular_values_plot([sys1, sys2])
```
generates

![Image](https://github.com/user-attachments/assets/66f2d7dd-3413-42bd-a3cf-e007676a69a6)

The following code works correctly in terms of colors:
```
ct.singular_values_plot(sys1)
ct.singular_values_plot(sys2)
```

![Image](https://github.com/user-attachments/assets/8b589767-463f-4793-8276-432058588811)

Note that the range of frequencies is different for each system, which is the reason you want to be able to call them as a list.

Hints from issue comments:

Solution patch:
diff --git a/.github/conda-env/doctest-env.yml b/.github/conda-env/doctest-env.yml
index a03b64ae7..4c0d36728 100644
--- a/.github/conda-env/doctest-env.yml
+++ b/.github/conda-env/doctest-env.yml
@@ -7,7 +7,7 @@ dependencies:
   - numpy
   - matplotlib
   - scipy
-  - sphinx
+  - sphinx<8.2
   - sphinx_rtd_theme
   - ipykernel
   - nbsphinx
diff --git a/.github/workflows/install_examples.yml b/.github/workflows/install_examples.yml
index cfbf40fe7..6893a99fb 100644
--- a/.github/workflows/install_examples.yml
+++ b/.github/workflows/install_examples.yml
@@ -20,7 +20,8 @@ jobs:
            --quiet --yes \
            python=3.12 pip \
            numpy matplotlib scipy \
-           slycot pmw jupyter
+           slycot pmw jupyter \
+           ipython!=9.0
 
     - name: Install from source
       run: |
diff --git a/control/freqplot.py b/control/freqplot.py
index fe258d636..048979960 100644
--- a/control/freqplot.py
+++ b/control/freqplot.py
@@ -2556,12 +2556,12 @@ def singular_values_plot(
             nyq_freq = None
 
         # Determine the color to use for this response
-        color = _get_color(
+        current_color = _get_color(
             color, fmt=fmt, offset=color_offset + idx_sys,
             color_cycle=color_cycle)
 
         # To avoid conflict with *fmt, only pass color kw if non-None
-        color_arg = {} if color is None else {'color': color}
+        color_arg = {} if current_color is None else {'color': current_color}
 
         # Decide on the system name
         sysname = response.sysname if response.sysname is not None \
diff --git a/control/iosys.py b/control/iosys.py
index 110552138..29f5bfefb 100644
--- a/control/iosys.py
+++ b/control/iosys.py
@@ -314,6 +314,9 @@ def _repr_latex_(self):
     def _repr_html_(self):
         # Defaults to using __repr__; override in subclasses
         return None
+    
+    def _repr_markdown_(self):
+        return self._repr_html_()
 
     @property
     def repr_format(self):


Test patch:
diff --git a/control/tests/freqplot_test.py b/control/tests/freqplot_test.py
index c0dfa4030..b3770486c 100644
--- a/control/tests/freqplot_test.py
+++ b/control/tests/freqplot_test.py
@@ -680,6 +680,39 @@ def test_display_margins(nsys, display_margins, gridkw, match):
         assert cplt.axes[0, 0].get_title() == ''
 
 
+def test_singular_values_plot_colors():
+    # Define some systems for testing
+    sys1 = ct.rss(4, 2, 2, strictly_proper=True)
+    sys2 = ct.rss(4, 2, 2, strictly_proper=True)
+
+    # Get the default color cycle
+    color_cycle = plt.rcParams['axes.prop_cycle'].by_key()['color']
+
+    # Plot the systems individually and make sure line colors are OK
+    cplt = ct.singular_values_plot(sys1)
+    assert cplt.lines.size == 1
+    assert len(cplt.lines[0]) == 2
+    assert cplt.lines[0][0].get_color() == color_cycle[0]
+    assert cplt.lines[0][1].get_color() == color_cycle[0]
+
+    cplt = ct.singular_values_plot(sys2)
+    assert cplt.lines.size == 1
+    assert len(cplt.lines[0]) == 2
+    assert cplt.lines[0][0].get_color() == color_cycle[1]
+    assert cplt.lines[0][1].get_color() == color_cycle[1]
+    plt.close('all')
+
+    # Plot the systems as a list and make sure colors are OK
+    cplt = ct.singular_values_plot([sys1, sys2])
+    assert cplt.lines.size == 2
+    assert len(cplt.lines[0]) == 2
+    assert len(cplt.lines[1]) == 2
+    assert cplt.lines[0][0].get_color() == color_cycle[0]
+    assert cplt.lines[0][1].get_color() == color_cycle[0]
+    assert cplt.lines[1][0].get_color() == color_cycle[1]
+    assert cplt.lines[1][1].get_color() == color_cycle[1]
+
+
 if __name__ == "__main__":
     #
     # Interactive mode: generate plots for manual viewing
diff --git a/control/tests/statesp_test.py b/control/tests/statesp_test.py
index 0806696f0..e3d78bbdd 100644
--- a/control/tests/statesp_test.py
+++ b/control/tests/statesp_test.py
@@ -1440,6 +1440,7 @@ def test_html_repr(gmats, ref, dt, dtref, repr_type, num_format, editsdefaults):
     dt_html = dtref.format(dt=dt, fmt=defaults['statesp.latex_num_format'])
     ref_html = ref[refkey].format(dt=dt_html)
     assert g._repr_html_() == ref_html
+    assert g._repr_html_() == g._repr_markdown_()
 
 
 @pytest.mark.parametrize(