Repository: geopandas/geopandas

Issue:
BUG: Inconsistent behavior in plot_dataframe when using aspect=None with missing_kwds
- [x] I have checked that this issue has not already been reported.

- [x] I have confirmed this bug exists on the latest version of geopandas.

- [ ] (optional) I have confirmed this bug exists on the main branch of geopandas.

---

#### Code Sample, a copy-pastable example

```python
import geopandas as gpd
import matplotlib.pyplot as plt
from shapely.geometry import Point

data = {
    'geometry': [Point(1, 1), Point(5, 5), Point(5, 10)],
    'value': [10, None, 10]
}

gdf = gpd.GeoDataFrame(data, crs="EPSG:4326")

fig, axes = plt.subplots(2,1)

gdf.plot(column='value', legend=True, aspect=None, ax=axes[0])
print("No missing_kwds, axes[0].get_aspect() = ", axes[0].get_aspect())

gdf.plot(column='value', missing_kwds={"color": "lightgray"}, legend=True, aspect=None, ax=axes[1])
print("With missing_kwds, axes[1].get_aspect() = ", axes[1].get_aspect())

plt.show()

```

#### Problem description

When plotting with `aspect=None` the aspect ratio of the resulting plot changes depending on whether or not a value for `missing_kwds` is passed. When no value for`missing_kwds` is passed, the aspect on the axis is "auto", as expected. However, when a value for `missing_kwds` is passed, the aspect on the axis is approximately 1.

#### Expected Output
The expected output when a value for `missing_kwds` is passed to `plot_dataframe` is an aspect value that is the same as the result when plotting without a passing a value for `missing_kwds`. In this case, the aspect should remain as `auto`.

#### A potential fix
I am able to fix this particular case by changing the line `geopandas/plotting.py:890` from
```
        plot_series(expl_series[nan_idx], ax=ax, **merged_kwds)
```
to
```
        plot_series(expl_series[nan_idx], ax=ax, aspect=aspect, **merged_kwds)
```
The problem is that `plot_series` has a default value for aspect which overrides the argument originally passed by the user. By passing the user's value to this internal call of `plot_series` , the expected output is produced.

If the maintainers agree with this solution to the problem, I am happy to resolve this issue via a PR with the above fix.

#### Output of ``geopandas.show_versions()``

<details>

SYSTEM INFO
-----------
python     : 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:40:32) [GCC 12.3.0]
executable : /home/klbonne/.local/miniconda3/envs/wntr/bin/python
machine    : Linux-6.3.13-060313-generic-x86_64-with-glibc2.35

GEOS, GDAL, PROJ INFO
---------------------
GEOS       : 3.11.1
GEOS lib   : None
GDAL       : 3.8.5
GDAL data dir: /home/klbonne/.local/miniconda3/envs/wntr/lib/python3.10/site-packages/pyogrio/gdal_data/
PROJ       : 9.2.1
PROJ data dir: /home/klbonne/.local/miniconda3/envs/wntr/lib/python3.10/site-packages/pyproj/proj_dir/share/proj

PYTHON DEPENDENCIES
-------------------
geopandas  : 1.0.1
numpy      : 1.26.4
pandas     : 2.0.3
pyproj     : 3.6.0
shapely    : 2.0.1
pyogrio    : 0.9.0
geoalchemy2: None
geopy      : None
matplotlib : 3.7.2
mapclassify: None
fiona      : 1.9.6
psycopg    : None
psycopg2   : None
pyarrow    : None

SYSTEM INFO
-----------
python     : 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:40:32) [GCC 12.3.0]
executable : /home/klbonne/.local/miniconda3/envs/wntr/bin/python
machine    : Linux-6.3.13-060313-generic-x86_64-with-glibc2.35

GEOS, GDAL, PROJ INFO
---------------------
GEOS       : 3.11.1
GEOS lib   : None
GDAL       : 3.8.5
GDAL data dir: /home/klbonne/.local/miniconda3/envs/wntr/lib/python3.10/site-packages/pyogrio/gdal_data/
PROJ       : 9.2.1
PROJ data dir: /home/klbonne/.local/miniconda3/envs/wntr/lib/python3.10/site-packages/pyproj/proj_dir/share/proj

PYTHON DEPENDENCIES
-------------------
geopandas  : 1.0.1
numpy      : 1.26.4
pandas     : 2.0.3
pyproj     : 3.6.0
shapely    : 2.0.1
pyogrio    : 0.9.0
geoalchemy2: None
geopy      : None
matplotlib : 3.7.2
mapclassify: None
fiona      : 1.9.6
psycopg    : None
psycopg2   : None
pyarrow    : None

</details>



Discussion:
Thanks! Fix is coming in #3438 

> `aspect=aspect`

It has to be `aspect=None`, otherwise with EPSG 4326, we would recompute the aspect.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 730ce8877b..100c14f39f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,32 +2,16 @@
 
 ## Version 1.1.0
 
-Notes on dependencies:
-
-- GeoPandas 1.1 now requires Python 3.10 or greater and pandas 2.0, numpy 1.24, pyproj 3.5,
-  are now the minimum required version for these dependencies.
-  Furthermore, the minimum tested version for optional dependencies has been updated to
-  fiona 1.8.21, scipy 1.9, matplotlib 3.7, mapclassify 2.5, folium 0.12 and
-  SQLAlchemy 2.0. Older versions of these libraries may continue to work, but are no longer
-  considered supported (#3371).
-
 New features and improvements:
 
 - Add ``grid_size`` parameter to ``union_all`` and ``dissolve`` (#3445).
-
-Bug fixes:
-
-- Fix an issue that showed numpy dtypes in bbox in `to_geo_dict` and `__geo_interface__`. (#3436)
-- Fix an issue in `sample_points` that could occasionally result in non-uniform distribution (#3470)
-
-New features and improvements:
-
 - `GeoDataFrame.plot` now supports `pd.Index` as an input for the `column` keyword (#3463).
-
-## Version 1.0.2 (???)
+- Avoid change of the plot aspect when plotting missing values (#3438).
 
 Bug fixes:
 
+- Fix an issue that showed numpy dtypes in bbox in `to_geo_dict` and `__geo_interface__`. (#3436)
+- Fix an issue in `sample_points` that could occasionally result in non-uniform distribution (#3470).
 - Fix unspecified layer warning being emitted while reading multilayer datasets, even
   when layer is specified when using the mask or bbox keywords (#3378).
 - Properly support named aggregations over a geometry column in `GroupBy.agg` (#3368).
@@ -38,7 +22,18 @@ Bug fixes:
 - Fix regression where `overlay` with `keep_geom_type` returns wrong results if the
   input contains invalid geometries (#3395).
 - Fix the dtype of the GeometryArray backing data being incorrect for zero length
-  GeoDataFrames causing errors in `overlay` (3424).
+  GeoDataFrames causing errors in `overlay` (#3424).
+- Fix regression where constructing a GeoSeries from a pd.Series with GeometryDtype values
+  failed when `crs` was provided (#3383).
+
+Notes on dependencies:
+
+- GeoPandas 1.1 now requires Python 3.10 or greater and pandas 2.0, numpy 1.24, pyproj 3.5,
+  are now the minimum required version for these dependencies.
+  Furthermore, the minimum tested version for optional dependencies has been updated to
+  fiona 1.8.21, scipy 1.9, matplotlib 3.7, mapclassify 2.5, folium 0.12 and
+  SQLAlchemy 2.0. Older versions of these libraries may continue to work, but are no longer
+  considered supported (#3371).
 
 Deprecations and compatibility notes:
 
diff --git a/geopandas/plotting.py b/geopandas/plotting.py
index 5b22236a6f..ae5e788f60 100644
--- a/geopandas/plotting.py
+++ b/geopandas/plotting.py
@@ -882,7 +882,7 @@ def plot_dataframe(
         merged_kwds = style_kwds.copy()
         merged_kwds.update(missing_kwds)
 
-        plot_series(expl_series[nan_idx], ax=ax, **merged_kwds)
+        plot_series(expl_series[nan_idx], ax=ax, **merged_kwds, aspect=None)
 
     if legend and not color:
         if legend_kwds is None:


Test patch:
diff --git a/geopandas/tests/test_plotting.py b/geopandas/tests/test_plotting.py
index e74f7a1ca0..83395ac82c 100644
--- a/geopandas/tests/test_plotting.py
+++ b/geopandas/tests/test_plotting.py
@@ -451,6 +451,17 @@ def test_no_missing_and_missing_kwds(self):
         df["category"] = df["values"].astype("str")
         df.plot("category", missing_kwds={"facecolor": "none"}, legend=True)
 
+    def test_missing_aspect(self):
+        self.df.loc[0, "values"] = np.nan
+        ax = self.df.plot(
+            "values",
+            missing_kwds={"color": "r"},
+            categorical=True,
+            legend=True,
+            aspect=2,
+        )
+        assert ax.get_aspect() == 2
+
 
 class TestPointZPlotting:
     def setup_method(self):