Repository: matplotlib/matplotlib

Issue:
# [Bug]: Axes.grid(color) ignores alpha

### Bug summary

When using Color like described here https://matplotlib.org/stable/tutorials/colors/colors.html for the Axes grid, the alpha value is ignored.

### Code for reproduction

```python
import numpy as np
fig, ax = plt.subplots()
rng = np.random.default_rng(12345)
ax.plot(rng.integers(low=0, high=10, size=3))
ax.grid(color=(0.8, 0.8, 0.8, 0))
fig.show()
```


### Actual outcome

![image](https://user-images.githubusercontent.com/572453/149469905-ea89d2fb-3caf-454b-835d-77797999c1e6.png)


### Expected outcome

![image](https://user-images.githubusercontent.com/572453/149469938-64b48de9-0d50-4280-a9e1-23d952571ff4.png)


### Additional information

_No response_

### Operating system

Windows

### Matplotlib Version

3.5.1

### Matplotlib Backend

module://backend_interagg

### Python version

3.9.2

### Jupyter version

_No response_

### Installation

pip

Implementation patch:
diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py
index c3b6fcac569f..900682511713 100644
--- a/lib/matplotlib/axis.py
+++ b/lib/matplotlib/axis.py
@@ -140,17 +140,20 @@ def __init__(
             f"grid.{major_minor}.linewidth",
             "grid.linewidth",
         )
-        if grid_alpha is None and not mcolors._has_alpha_channel(grid_color):
-            # alpha precedence: kwarg > color alpha > rcParams['grid.alpha']
-            # Note: only resolve to rcParams if the color does not have alpha
-            # otherwise `grid(color=(1, 1, 1, 0.5))` would work like
-            #   grid(color=(1, 1, 1, 0.5), alpha=rcParams['grid.alpha'])
-            # so the that the rcParams default would override color alpha.
-            grid_alpha = mpl._val_or_rc(
-                # grid_alpha is None so we can use the first key
-                mpl.rcParams[f"grid.{major_minor}.alpha"],
-                "grid.alpha",
-            )
+        if grid_alpha is None:
+            if mcolors._has_alpha_channel(grid_color):
+                # Extract alpha from the color
+                # alpha precedence: kwarg > color alpha > rcParams['grid.alpha']
+                rgba = mcolors.to_rgba(grid_color)
+                grid_color = rgba[:3]  # RGB only
+                grid_alpha = rgba[3]    # Alpha from color
+            else:
+                # No alpha in color, use rcParams
+                grid_alpha = mpl._val_or_rc(
+                    # grid_alpha is None so we can use the first key
+                    mpl.rcParams[f"grid.{major_minor}.alpha"],
+                    "grid.alpha",
+                )
 
         grid_kw = {k[5:]: v for k, v in kwargs.items() if k != "rotation_mode"}
 
@@ -348,6 +351,15 @@ def _apply_params(self, **kwargs):
 
         grid_kw = {k[5:]: v for k, v in kwargs.items()
                    if k in _gridline_param_names}
+        # If grid_color has an alpha channel and grid_alpha is not explicitly
+        # set, extract the alpha from the color.
+        if 'color' in grid_kw and 'alpha' not in grid_kw:
+            grid_color = grid_kw['color']
+            if mcolors._has_alpha_channel(grid_color):
+                # Convert to rgba to extract alpha
+                rgba = mcolors.to_rgba(grid_color)
+                grid_kw['color'] = rgba[:3]  # RGB only
+                grid_kw['alpha'] = rgba[3]    # Alpha channel
         self.gridline.set(**grid_kw)
 
     def update_position(self, loc):


Test patch:
diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py
index 6e839ef2f189..b9076d86dc98 100644
--- a/lib/matplotlib/tests/test_axes.py
+++ b/lib/matplotlib/tests/test_axes.py
@@ -6133,6 +6133,21 @@ def test_grid():
     assert not ax.xaxis.majorTicks[0].gridline.get_visible()
 
 
+def test_grid_color_with_alpha():
+    """Test that grid(color=(..., alpha)) respects the alpha value."""
+    fig, ax = plt.subplots()
+    ax.grid(True, color=(0.5, 0.6, 0.7, 0.3))
+
+    # Check that alpha is extracted from color tuple
+    for tick in ax.xaxis.get_major_ticks():
+        assert tick.gridline.get_alpha() == 0.3, \
+            f"Expected alpha=0.3, got {tick.gridline.get_alpha()}"
+
+    for tick in ax.yaxis.get_major_ticks():
+        assert tick.gridline.get_alpha() == 0.3, \
+            f"Expected alpha=0.3, got {tick.gridline.get_alpha()}"
+
+
 def test_reset_grid():
     fig, ax = plt.subplots()
     ax.tick_params(reset=True, which='major', labelsize=10)