Repository: sunpy/sunpy

Issue:
Add STEREO EUVI colourmap
It doesn't look like sunpy has a built in colourmap for STEREO EUVI: https://docs.sunpy.org/en/stable/code_ref/visualization.html#module-sunpy.visualization.colormaps - it would be good to have one added.


Discussion:
I would like to work on it. @dstansby what's the reference for adding color maps, from which numpy arrays in `color_tables`are formed? I googled and found this php script https://heliodocs.com/xdoc/xdoc_print.php?file=$SSW/stereo/secchi/idl/display/secchi_colors.pro .
Yes, that looks right. I don't know the details myself, but maybe you could work it out by working out what's already in the sunpy code for other colormaps.
See also #3885. 

Resolving patch:
diff --git a/sunpy/map/sources/stereo.py b/sunpy/map/sources/stereo.py
--- a/sunpy/map/sources/stereo.py
+++ b/sunpy/map/sources/stereo.py
@@ -34,7 +34,7 @@ def __init__(self, data, header, **kwargs):
 
         GenericMap.__init__(self, data, header, **kwargs)
         self._nickname = "{}-{}".format(self.detector, self.observatory[-1])
-        self.plot_settings['cmap'] = 'sohoeit{wl:d}'.format(wl=int(self.wavelength.value))
+        self.plot_settings['cmap'] = 'euvi{wl:d}'.format(wl=int(self.wavelength.value))
         self.plot_settings['norm'] = ImageNormalize(
             stretch=source_stretch(self.meta, PowerStretch(0.25)), clip=False)
         self.meta['waveunit'] = 'Angstrom'
diff --git a/sunpy/visualization/colormaps/cm.py b/sunpy/visualization/colormaps/cm.py
--- a/sunpy/visualization/colormaps/cm.py
+++ b/sunpy/visualization/colormaps/cm.py
@@ -79,6 +79,11 @@
 rhessi = ct.rhessi_color_table()
 std_gamma_2 = ct.std_gamma_2()
 
+euvi195 = ct.euvi_color_table(195*u.angstrom)
+euvi284 = ct.euvi_color_table(284*u.angstrom)
+euvi304 = ct.euvi_color_table(304*u.angstrom)
+euvi171 = ct.euvi_color_table(171*u.angstrom)
+
 cmlist = {
     'goes-rsuvi94': goesrsuvi94,
     'goes-rsuvi131': goesrsuvi131,
@@ -133,6 +138,10 @@
     'kcor': kcor,
     'rhessi': rhessi,
     'std_gamma_2': std_gamma_2,
+    'euvi171': euvi171,
+    'euvi195': euvi195,
+    'euvi284': euvi284,
+    'euvi304': euvi304,
 }
 
 # Register the colormaps with matplotlib so plt.get_cmap('sdoaia171') works
diff --git a/sunpy/visualization/colormaps/color_tables.py b/sunpy/visualization/colormaps/color_tables.py
--- a/sunpy/visualization/colormaps/color_tables.py
+++ b/sunpy/visualization/colormaps/color_tables.py
@@ -14,7 +14,7 @@
     'aia_color_table', 'sswidl_lasco_color_table', 'eit_color_table',
     'sxt_color_table', 'xrt_color_table', 'trace_color_table',
     'sot_color_table', 'hmi_mag_color_table', 'suvi_color_table',
-    'rhessi_color_table', 'std_gamma_2',
+    'rhessi_color_table', 'std_gamma_2', 'euvi_color_table',
 ]
 
 cmap_data_dir = pathlib.Path(__file__).parent.absolute() / 'data'
@@ -306,6 +306,16 @@ def rhessi_color_table():
 def std_gamma_2():
     return cmap_from_rgb_file("std_gamma_2", "std_gamma_2.csv")
 
+def euvi_color_table(wavelength: u.angstrom):
+
+    try:
+        return cmap_from_rgb_file(f'EUVI {str(wavelength)}', f'euvi_{int(wavelength.value)}.csv')
+    except OSError:
+        raise ValueError(
+            "Invalid EUVI wavelength. Valid values are "
+            "171, 195, 284, 304."
+        )
+
 def cmap_from_rgb_file(name, fname):
     """
     Create a colormap from a RGB .csv file.
@@ -339,7 +349,7 @@ def create_cdict(r, g, b):
     """
     Create the color tuples in the correct format.
     """
-    i = np.linspace(0, 1, r0.size)
+    i = np.linspace(0, 1, r.size)
 
     cdict = {name: list(zip(i, el / 255.0, el / 255.0))
              for el, name in [(r, 'red'), (g, 'green'), (b, 'blue')]}


Test patch:
diff --git a/sunpy/tests/figure_hashes_mpl_332_ft_261_astropy_403.json b/sunpy/tests/figure_hashes_mpl_332_ft_261_astropy_403.json
--- a/sunpy/tests/figure_hashes_mpl_332_ft_261_astropy_403.json
+++ b/sunpy/tests/figure_hashes_mpl_332_ft_261_astropy_403.json
@@ -51,5 +51,5 @@
   "sunpy.visualization.animator.tests.test_wcs.test_array_animator_wcs_coord_params": "e1678a7b513917e177547b8ee0a93ee2f29a6d3dacff5fa213355ff414e706b1",
   "sunpy.visualization.animator.tests.test_wcs.test_array_animator_wcs_coord_params_no_ticks": "ce35b25eb2c4eb6d2ce56d6a78c8a33b1bfdf8ef00b098c7c2c08feae2a82356",
   "sunpy.visualization.animator.tests.test_wcs.test_array_animator_wcs_coord_params_grid": "4bb5930ec573f8399470df023d4686601728d35a70527c397f7eed39d07ba0e3",
-  "sunpy.visualization.colormaps.tests.test_cm.test_cmap_visual": "453d75b2a1c180c31363fdb2faa3f60bc4433ded53dde4678e91b7986f85bf00"
+  "sunpy.visualization.colormaps.tests.test_cm.test_cmap_visual": "a2a4885b1bcdef40626bef1e8e9be1b7469530beae47a8c75f25aa697a708b4f"
 }
diff --git a/sunpy/tests/figure_hashes_mpl_dev_ft_261_astropy_dev.json b/sunpy/tests/figure_hashes_mpl_dev_ft_261_astropy_dev.json
--- a/sunpy/tests/figure_hashes_mpl_dev_ft_261_astropy_dev.json
+++ b/sunpy/tests/figure_hashes_mpl_dev_ft_261_astropy_dev.json
@@ -51,5 +51,5 @@
   "sunpy.visualization.animator.tests.test_wcs.test_array_animator_wcs_coord_params": "e1678a7b513917e177547b8ee0a93ee2f29a6d3dacff5fa213355ff414e706b1",
   "sunpy.visualization.animator.tests.test_wcs.test_array_animator_wcs_coord_params_no_ticks": "ce35b25eb2c4eb6d2ce56d6a78c8a33b1bfdf8ef00b098c7c2c08feae2a82356",
   "sunpy.visualization.animator.tests.test_wcs.test_array_animator_wcs_coord_params_grid": "4bb5930ec573f8399470df023d4686601728d35a70527c397f7eed39d07ba0e3",
-  "sunpy.visualization.colormaps.tests.test_cm.test_cmap_visual": "453d75b2a1c180c31363fdb2faa3f60bc4433ded53dde4678e91b7986f85bf00"
+  "sunpy.visualization.colormaps.tests.test_cm.test_cmap_visual": "a2a4885b1bcdef40626bef1e8e9be1b7469530beae47a8c75f25aa697a708b4f"
 }