Repository: matplotlib/matplotlib
Pull request: FIX: Reset label of axis to center
## PR Summary
Fixes #21772 
1) Added elif blocks to center `xlabel` and `ylabel`
2) Added a test for the same in `test_axes.py`
3) Additionally, in `set_ylabel`, the `horizontalalignment` was getting reset instead of `verticalalignment`

## PR Checklist

**Tests and Styling**
- [x] Has pytest style unit tests (and `pytest` passes).
- [x] Is [Flake 8](https://flake8.pycqa.org/en/latest/) compliant (install `flake8-docstrings` and run `flake8 --docstring-convention=all`).

**Documentation**
- [N/A] New features are documented, with examples if plot related.
- [N/A] New features have an entry in `doc/users/next_whats_new/` (follow instructions in README.rst there).
- [N/A] API changes documented in `doc/api/next_api_changes/` (follow instructions in README.rst there).
- [N/A] Documentation is sphinx and numpydoc compliant (the docs should [build](https://matplotlib.org/devel/documenting_mpl.html#building-the-docs) without error).

Problem statement:
[Bug]:  cannot reset label of axis to center
### Bug summary

When I do once of setting xlabel of ylabel to left of right, it cannot reset label of axis to center any way.

### Code for reproduction

```python
if I do once:
ax.set_xlabel("my label",loc="left ") 
or:
ax.set_xlabel("my label",loc="right")
the following will have no any effect:
ax.set_xlabel("my label",loc="center")
```


### Actual outcome

No any output

### Expected outcome

reset the label to center 

### Additional information

_No response_

### Operating system

win 10 x64

### Matplotlib Version

3.4.3 and 3.5

### Matplotlib Backend

Qt5, Qt6,

### Python version

3.9, 3,10

### Jupyter version

_No response_

### Installation

pip

Hints from issue discussion:
Confirmed.  Note that if you do `set_xlabel('label', loc='left'); set_xlabel('label', loc='right');` it works, so "center" is being ignored.  This is an easy fix, so I'll mark as good first issue.  It just needs a fix in `set_xlabel` and `set_ylabel` and it requires a test in `test_axes.py`.  
@jklymak This seems to be just another ``elif`` clause in the function definition, right? Currently, the ``kwargs.update`` sets ``x=0`` for left, ``x=1`` for right. Should center then be ``x=2`` or should this be renumbered? I'm not sure if I understand this correctly...

Commit message: Fix label shift and add test

Patch to review:
diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py
index 7a309780c3d7..f423530fd6e6 100644
--- a/lib/matplotlib/axes/_base.py
+++ b/lib/matplotlib/axes/_base.py
@@ -3494,6 +3494,8 @@ def set_xlabel(self, xlabel, fontdict=None, labelpad=None, *,
         _api.check_in_list(('left', 'center', 'right'), loc=loc)
         if loc == 'left':
             kwargs.update(x=0, horizontalalignment='left')
+        elif loc == 'center':
+            kwargs.update(x=0.5, horizontalalignment='center')
         elif loc == 'right':
             kwargs.update(x=1, horizontalalignment='right')
         return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
@@ -3837,9 +3839,11 @@ def set_ylabel(self, ylabel, fontdict=None, labelpad=None, *,
                    else mpl.rcParams['yaxis.labellocation'])
         _api.check_in_list(('bottom', 'center', 'top'), loc=loc)
         if loc == 'bottom':
-            kwargs.update(y=0, horizontalalignment='left')
+            kwargs.update(y=0, verticalalignment='bottom')
+        elif loc == 'center':
+            kwargs.update(y=0.5, verticalalignment='center')
         elif loc == 'top':
-            kwargs.update(y=1, horizontalalignment='right')
+            kwargs.update(y=1, verticalalignment='top')
         return self.yaxis.set_label_text(ylabel, fontdict, **kwargs)
 
     def invert_yaxis(self):
diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py
index 5f6d528a3634..27d86d450e89 100644
--- a/lib/matplotlib/tests/test_axes.py
+++ b/lib/matplotlib/tests/test_axes.py
@@ -105,6 +105,30 @@ def test_label_loc_rc(fig_test, fig_ref):
     cbar.set_label("Z Label", x=1, ha='right')
 
 
+def test_label_shift():
+    fig, ax = plt.subplots()
+
+    # Test label re-centering on x-axis
+    ax.set_xlabel("Test label", loc="left")
+    ax.set_xlabel("Test label", loc="center")
+    assert ax.xaxis.get_label()._x == 0.5
+    ax.set_xlabel("Test label", loc="right")
+    assert ax.xaxis.get_label()._x == 1.0
+    ax.set_xlabel("Test label", loc="center")
+    assert ax.xaxis.get_label()._x == 0.5
+
+    # Test label re-centering on y-axis
+    ax.set_ylabel("Test label", loc="top")
+    ax.set_ylabel("Test label", loc="center")
+    assert ax.yaxis.get_label()._y == 0.5
+    ax.set_ylabel("Test label", loc="bottom")
+    assert ax.yaxis.get_label()._y == 0.0
+    ax.set_ylabel("Test label", loc="center")
+    assert ax.yaxis.get_label()._y == 0.5
+
+    plt.close()
+
+
 @check_figures_equal(extensions=["png"])
 def test_acorr(fig_test, fig_ref):
     np.random.seed(19680801)


Code review comments:
diff_hunk: @@ -3837,9 +3839,11 @@ def set_ylabel(self, ylabel, fontdict=None, labelpad=None, *,
                    else mpl.rcParams['yaxis.labellocation'])
         _api.check_in_list(('bottom', 'center', 'top'), loc=loc)
         if loc == 'bottom':
-            kwargs.update(y=0, horizontalalignment='left')
+            kwargs.update(y=0, verticalalignment='bottom')
+        elif loc == 'center':
+            kwargs.update(y=0.5, verticalalignment='center')
         elif loc == 'top':
-            kwargs.update(y=1, horizontalalignment='right')
+            kwargs.update(y=1, verticalalignment='top')
path: lib/matplotlib/axes/_base.py
text: @user1:
I don't think this change is correct, is it?  horizontal alignment is relative to spinning 90 degrees I think.

diff_hunk: @@ -105,6 +105,30 @@ def test_label_loc_rc(fig_test, fig_ref):
     cbar.set_label("Z Label", x=1, ha='right')
 
 
+def test_label_shift():
+    fig, ax = plt.subplots()
+
+    # Test label re-centering on x-axis
+    ax.set_xlabel("Test label", loc="left")
+    ax.set_xlabel("Test label", loc="center")
+    assert ax.xaxis.get_label()._x == 0.5
path: lib/matplotlib/tests/test_axes.py
text: @user1:
We try to only test public interface and `._x` is private.  Can you change to a test of the public getter?

@author:
@user1 Ah my bad; thanks for the feedback! Updated the code. Let me know if it looks good now.