internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: geopandas/geopandas

Issue:
BUG: __finalize__ does not copies .attrs
- [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 master branch of geopandas.

---

#### Problem description

Dataframe .attrs attributes are lost after explode().
It seems that geopandas and geoseries __finalize__ is not copying .attrs while pandas version is.

This bug exists in version 0.9


Discussion:
Thanks, I can confirm the issue. We should look into that. We've added the support of `attrs` in #1658 but this case slipped.

MRE:
```py
>>> import geopandas as gpd
>>> df = gpd.read_file(gpd.datasets.get_path('nybb'))
>>> df.attrs = {'test': "value"}
>>> df.explode().attrs
{}
```

Resolving patch:
diff --git a/geopandas/geodataframe.py b/geopandas/geodataframe.py
--- a/geopandas/geodataframe.py
+++ b/geopandas/geodataframe.py
@@ -1584,7 +1584,8 @@ def explode(self, column=None, **kwargs):
 
         df = pd.concat(
             [df_copy.drop(df_copy._geometry_column_name, axis=1), exploded_geom], axis=1
-        )
+        ).__finalize__(self)
+
         # reset to MultiIndex, otherwise df index is only first level of
         # exploded GeoSeries index.
         df.set_index(exploded_index, append=True, inplace=True)


Test patch:
diff --git a/geopandas/tests/test_pandas_methods.py b/geopandas/tests/test_pandas_methods.py
--- a/geopandas/tests/test_pandas_methods.py
+++ b/geopandas/tests/test_pandas_methods.py
@@ -558,6 +558,10 @@ def test_preserve_attrs(df):
     df2 = df.reset_index()
     assert df2.attrs == attrs
 
+    # https://github.com/geopandas/geopandas/issues/1875
+    df3 = df2.explode()
+    assert df3.attrs == attrs
+
 
 @pytest.mark.skipif(not compat.PANDAS_GE_12, reason="attrs introduced in pandas 1.0")
 def test_preserve_flags(df):
Repository: geopandas/geopandas

Issue:
BUG: active geometry information lost after apply
GeoDataFrame loses information on an active geometry column after `apply` if that is not called `geometry`.

```py
df = gpd.read_file(gpd.datasets.get_path('nybb'))
df = df.rename_geometry('geom')
result = df.apply(lambda col: col, axis=0)

result.geometry

AttributeError: No geometry data set yet (expected in column 'geometry'.)
```


Discussion:
Can I work on fixing this?
@m-richards yes, it hasn't be fixed yet. Thanks!

Resolving patch:
diff --git a/geopandas/geodataframe.py b/geopandas/geodataframe.py
--- a/geopandas/geodataframe.py
+++ b/geopandas/geodataframe.py
@@ -1387,8 +1387,10 @@ def apply(self, func, axis=0, raw=False, result_type=None, args=(), **kwargs):
         if (
             isinstance(result, GeoDataFrame)
             and self._geometry_column_name in result.columns
-            and any(isinstance(t, GeometryDtype) for t in result.dtypes)
+            and isinstance(result[self._geometry_column_name].dtype, GeometryDtype)
         ):
+            # apply calls _constructor which resets geom col name to geometry
+            result._geometry_column_name = self._geometry_column_name
             if self.crs is not None and result.crs is None:
                 result.set_crs(self.crs, inplace=True)
         return result


Test patch:
diff --git a/geopandas/tests/test_pandas_methods.py b/geopandas/tests/test_pandas_methods.py
--- a/geopandas/tests/test_pandas_methods.py
+++ b/geopandas/tests/test_pandas_methods.py
@@ -539,6 +539,12 @@ def test_apply_no_geometry_result(df, crs):
     assert_frame_equal(result, expected)
 
 
+def test_apply_preserves_geom_col_name(df):
+    df = df.rename_geometry("geom")
+    result = df.apply(lambda col: col, axis=0)
+    assert result.geometry.name == "geom"
+
+
 @pytest.mark.skipif(not compat.PANDAS_GE_10, reason="attrs introduced in pandas 1.0")
 def test_preserve_attrs(df):
     # https://github.com/geopandas/geopandas/issues/1654
Repository: geopandas/geopandas

Issue:
BUG: inconsistent sjoin suffix
- [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.

- [x] (optional) I have confirmed this bug exists on the master branch of geopandas.

---


#### Code Sample, a copy-pastable example

```python
>>> df = gpd.sjoin(cities, countries, how="left")
>>> df.columns
Index(['name_left', 'geometry', 'index_right', 'pop_est', 'continent',
       'name_right', 'iso_a3', 'gdp_md_est'],
      dtype='object')

>>> df = gpd.sjoin(cities, countries, how="right")
>>> df.columns
Index(['index_left', 'name_x', 'pop_est', 'continent', 'name_y', 'iso_a3',
       'gdp_md_est', 'geometry'],
      dtype='object')
```

#### Problem description

When you do the `"left"` or `"inner"` join, columns with the same name get suffixes `_left` and `_right` but when you do the `"right"` join, suffixes are `_x` and `_y`. That means that `lsuffix="left", rsuffix="right"` is ignored.


Discussion:

Resolving patch:
diff --git a/geopandas/tools/sjoin.py b/geopandas/tools/sjoin.py
--- a/geopandas/tools/sjoin.py
+++ b/geopandas/tools/sjoin.py
@@ -319,6 +319,7 @@ def _frame_join(indices, left_df, right_df, how, lsuffix, rsuffix):
                 left_index=True,
                 right_on="_key_left",
                 how="right",
+                suffixes=("_{}".format(lsuffix), "_{}".format(rsuffix)),
             )
             .set_index(index_right)
             .drop(["_key_left", "_key_right"], axis=1)


Test patch:
diff --git a/geopandas/tools/tests/test_sjoin.py b/geopandas/tools/tests/test_sjoin.py
--- a/geopandas/tools/tests/test_sjoin.py
+++ b/geopandas/tools/tests/test_sjoin.py
@@ -89,6 +89,23 @@ def dfs(request):
 
 
 class TestSpatialJoin:
+    @pytest.mark.parametrize(
+        "how, lsuffix, rsuffix, expected_cols",
+        [
+            ("left", "left", "right", {"col_left", "col_right", "index_right"}),
+            ("inner", "left", "right", {"col_left", "col_right", "index_right"}),
+            ("right", "left", "right", {"col_left", "col_right", "index_left"}),
+            ("left", "lft", "rgt", {"col_lft", "col_rgt", "index_rgt"}),
+            ("inner", "lft", "rgt", {"col_lft", "col_rgt", "index_rgt"}),
+            ("right", "lft", "rgt", {"col_lft", "col_rgt", "index_lft"}),
+        ],
+    )
+    def test_suffixes(self, how: str, lsuffix: str, rsuffix: str, expected_cols):
+        left = GeoDataFrame({"col": [1], "geometry": [Point(0, 0)]})
+        right = GeoDataFrame({"col": [1], "geometry": [Point(0, 0)]})
+        joined = sjoin(left, right, how=how, lsuffix=lsuffix, rsuffix=rsuffix)
+        assert set(joined.columns) == expected_cols | set(("geometry",))
+
     @pytest.mark.parametrize("dfs", ["default-index", "string-index"], indirect=True)
     def test_crs_mismatch(self, dfs):
         index, df1, df2, expected = dfs
Repository: geopandas/geopandas

Issue:
ENH: Allow `hex` kwarg in GeoSeries.from_wkb
#### Is your feature request related to a problem?

With `GeoSeries.from_wkb` in shapely mode I get this error with a hex encoded geometry:
```
~/.../lib/python3.8/site-packages/shapely/geos.py in read(self, data)
    426         """Returns geometry from WKB"""
    427         geom = self._lgeos.GEOSWKBReader_read(
--> 428             self._reader, c_char_p(data), c_size_t(len(data)))
    429         if not geom:
    430             raise WKBReadingError(

TypeError: bytes or integer address expected instead of str instance
```
This is due to the fact that the `hex=True` kwargs is needed. This is not necessary for the `pygeos` engine.

It works with:
```
pdf.geometry.apply(lambda geom: shapely.wkb.loads(geom, hex=True))
```

#### Describe the solution you'd like

```python
GeoSeries.from_wkb(pdf.geometry, hex=True)
```

#### API breaking implications

It will add the `hex` kwarg.


Discussion:
I guess an alternative could be to handle automatically. Something like:
```python
if isinstance(geom, str):
    hex = True
```
pygeos doesn't mind if it is hex or not? If so I'd try to automatically resolve it under the hood in `from_wkb` here https://github.com/geopandas/geopandas/blob/187287b2fac8216bcc56ba6d5c5074ff6ce6dd3d/geopandas/_vectorized.py#L159

PR is welcome (as always :))!

Resolving patch:
diff --git a/geopandas/_vectorized.py b/geopandas/_vectorized.py
--- a/geopandas/_vectorized.py
+++ b/geopandas/_vectorized.py
@@ -169,7 +169,7 @@ def from_wkb(data):
 
     for geom in data:
         if not isna(geom) and len(geom):
-            geom = shapely.wkb.loads(geom)
+            geom = shapely.wkb.loads(geom, hex=isinstance(geom, str))
         else:
             geom = None
         out.append(geom)


Test patch:
diff --git a/geopandas/tests/test_array.py b/geopandas/tests/test_array.py
--- a/geopandas/tests/test_array.py
+++ b/geopandas/tests/test_array.py
@@ -158,6 +158,16 @@ def test_from_wkb():
     assert res[0] == multi_poly
 
 
+def test_from_wkb_hex():
+    geometry_hex = ["0101000000CDCCCCCCCCCC1440CDCCCCCCCC0C4A40"]
+    res = from_wkb(geometry_hex)
+    assert isinstance(res, GeometryArray)
+
+    # array
+    res = from_wkb(np.array(geometry_hex, dtype=object))
+    assert isinstance(res, GeometryArray)
+
+
 def test_to_wkb():
     P = from_shapely(points_no_missing)
     res = to_wkb(P)
Repository: geopandas/geopandas

Issue:
REGR: regression in explode's MultiIndex creation when using pygeos
#1945 introduced a slight performance regression in `GeoSeries.explode()` when using `pygeos`, as the new series' MultiIndex is created using `from_tuples` instead of `from_arrays`. The former calling the latter, it's necessarily less performant, particularly here since the needed arrays are computed, then converted to a list of tuples using a list comprehension, only to be passed to `from_tuples` and converted back to arrays.

The list of arrays is simply the output of  `get_level_values` for each level of the original index plus the new `inner_index`, which is computed in `explode`. So the fix to go back to using `from_arrays` is rather straightforward I think.

Shall I open a PR for this?




Discussion:
> Shall I open a PR for this?

Yes please :)

Resolving patch:
diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py
--- a/geopandas/geoseries.py
+++ b/geopandas/geoseries.py
@@ -812,13 +812,13 @@ def explode(self):
             # extract original index values based on integer index
             outer_index = self.index.take(outer_idx)
 
-            index = zip(outer_index, inner_index)
+            nlevels = outer_index.nlevels
+            index_arrays = [outer_index.get_level_values(lvl) for lvl in range(nlevels)]
+            index_arrays.append(inner_index)
 
-            # if self.index is a MultiIndex then index is a list of nested tuples
-            if isinstance(self.index, MultiIndex):
-                index = [tuple(outer) + (inner,) for outer, inner in index]
-
-            index = MultiIndex.from_tuples(index, names=self.index.names + [None])
+            index = MultiIndex.from_arrays(
+                index_arrays, names=self.index.names + [None]
+            )
             return GeoSeries(geometries, index=index, crs=self.crs).__finalize__(self)
 
         # else PyGEOS is not available or version <= 0.8


Test patch:
Repository: geopandas/geopandas

Issue:
BUG: explore() method - vmin is ignored if it is lower as the minimum of the values
Can make up a small reproducer later, just putting it here already to not forget about it


Discussion:
A reproducer would be nice because it seems to work on my end.

```py
nybb.explore("BoroCode", vmin=-10)
```
![Screenshot 2021-10-13 at 11 00 11](https://user-images.githubusercontent.com/36797143/137112076-21cee148-129f-4898-902e-fc2a05f3420d.png)

Reproducer:

```
nybb = geopandas.read_file(geopandas.datasets.get_path("nybb"))

nybb["values"] = nybb["BoroCode"] * 10.0
nybb[nybb["values"] >= 30].explore(column="values", vmin=0, vmax=45)
```

First guess without looking at the code is that it might be due to the fact I am using `vmin=0` (value zero, which is treated as falsy, we have had that issue with plot() as well, I seem to remember)
> might be due to the fact I am using vmin=0

quite likely, because everything else works (1, -1). I'll have a look at fix.

Resolving patch:
diff --git a/geopandas/explore.py b/geopandas/explore.py
--- a/geopandas/explore.py
+++ b/geopandas/explore.py
@@ -396,8 +396,8 @@ def my_colormap(value):  # scalar value defined in 'column'
             color = list(map(lambda x: cmap(x), df[column]))
 
         else:
-            vmin = gdf[column].min() if not vmin else vmin
-            vmax = gdf[column].max() if not vmax else vmax
+            vmin = gdf[column].min() if vmin is None else vmin
+            vmax = gdf[column].max() if vmax is None else vmax
 
             # get bins
             if scheme is not None:


Test patch:
diff --git a/geopandas/tests/test_explore.py b/geopandas/tests/test_explore.py
--- a/geopandas/tests/test_explore.py
+++ b/geopandas/tests/test_explore.py
@@ -466,6 +466,20 @@ def test_vmin_vmax(self):
         assert 'case"119":return{"color":"#414287","fillColor":"#414287"' in out_str
         assert 'case"3":return{"color":"#482173","fillColor":"#482173"' in out_str
 
+        # test 0
+        df2 = self.nybb.copy()
+        df2["values"] = df2["BoroCode"] * 10.0
+        m = df2[df2["values"] >= 30].explore("values", vmin=0)
+        out_str = self._fetch_map_string(m)
+        assert 'case"1":return{"color":"#7ad151","fillColor":"#7ad151"' in out_str
+        assert 'case"2":return{"color":"#22a884","fillColor":"#22a884"' in out_str
+
+        df2["values_negative"] = df2["BoroCode"] * -10.0
+        m = df2[df2["values_negative"] <= 30].explore("values_negative", vmax=0)
+        out_str = self._fetch_map_string(m)
+        assert 'case"1":return{"color":"#414487","fillColor":"#414487"' in out_str
+        assert 'case"2":return{"color":"#2a788e","fillColor":"#2a788e"' in out_str
+
     def test_missing_vals(self):
         m = self.missing.explore("continent")
         assert '"fillColor":null' in self._fetch_map_string(m)
Repository: geopandas/geopandas

Issue:
TST: tests with invalid values fail with pandas master
We have some recent failures coming from pandas master - 
https://github.com/geopandas/geopandas/runs/4059704198?check_suite_focus=true

All seem to be related to the handling of invalid values but I guess that the fix should happen in pandas? I've got no bandwidth now, so filing it to keep an eye on it.


Discussion:
Will take a look after the weekend

Resolving patch:
diff --git a/geopandas/array.py b/geopandas/array.py
--- a/geopandas/array.py
+++ b/geopandas/array.py
@@ -363,10 +363,12 @@ def __getitem__(self, idx):
             # for pandas >= 1.0, validate and convert IntegerArray/BooleanArray
             # to numpy array, pass-through non-array-like indexers
             idx = pd.api.indexers.check_array_indexer(self, idx)
-        if isinstance(idx, (Iterable, slice)):
             return GeometryArray(self.data[idx], crs=self.crs)
         else:
-            raise TypeError("Index type not supported", idx)
+            if isinstance(idx, (Iterable, slice)):
+                return GeometryArray(self.data[idx], crs=self.crs)
+            else:
+                raise TypeError("Index type not supported", idx)
 
     def __setitem__(self, key, value):
         if compat.PANDAS_GE_10:
@@ -740,8 +742,9 @@ def to_crs(self, crs=None, epsg=None):
 
         >>> a = a.to_crs(3857)
         >>> to_wkt(a)
-        array(['POINT (111319 111325)', 'POINT (222639 222684)',
-               'POINT (333958 334111)'], dtype=object)
+        array(['POINT (111319.490793 111325.142866)',
+               'POINT (222638.981587 222684.208506)',
+               'POINT (333958.47238 334111.171402)'], dtype=object)
         >>> a.crs  # doctest: +SKIP
         <Projected CRS: EPSG:3857>
         Name: WGS 84 / Pseudo-Mercator


Test patch:
diff --git a/geopandas/tests/test_extension_array.py b/geopandas/tests/test_extension_array.py
--- a/geopandas/tests/test_extension_array.py
+++ b/geopandas/tests/test_extension_array.py
@@ -231,6 +231,18 @@ def as_array(request):
     return request.param
 
 
+@pytest.fixture
+def invalid_scalar(data):
+    """
+    A scalar that *cannot* be held by this ExtensionArray.
+
+    The default should work for most subclasses, but is not guaranteed.
+
+    If the array can hold any item (i.e. object dtype), then use pytest.skip.
+    """
+    return object.__new__(object)
+
+
 # Fixtures defined in pandas/conftest.py that are also needed: defining them
 # here instead of importing for compatibility
Repository: geopandas/geopandas

Issue:
DOC: Include links to matplotlib documentation in GeoDataFrame.plot() documentation
In the documentation for [GeoDataFrame.plot()](https://geopandas.org/docs/reference/api/geopandas.GeoDataFrame.plot.htm) would like the [matplotlib.pyplot.legend() and matplotlib.pyplot.colorbar() functions](https://geopandas.org/docs/reference/api/geopandas.GeoDataFrame.plot.html#:~:text=matplotlib.pyplot.legend()%20or%20matplotlib.pyplot.colorbar()) to link to their respective matplotlib documentation. 

Docs for  [matplotlib.pyplot.legend()](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html) and  [matplotlib.pyplot.colorbar()](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.colorbar.html)


I think this is relevant change because it's not immediately clear what keyword args can be used in legend args and inclusion of these links makes this more clear.


Discussion:
Thanks for the suggestion! This would be nice, we can use intersphinx mapping to ensure the links are correctly preserved long-term. A PR would be welcome!
Hi team - if noone else has put their hand up I'd love this as a first issue for me.

Might ask some questions if I run into problems with that intersphinx mapping.
@ryanward-io Go for it! Thanks!

Feel free to prepare a draft PR and we can resolve all questions there. 

Resolving patch:
diff --git a/geopandas/plotting.py b/geopandas/plotting.py
--- a/geopandas/plotting.py
+++ b/geopandas/plotting.py
@@ -563,8 +563,8 @@ def plot_dataframe(
         Size of the resulting matplotlib.figure.Figure. If the argument
         axes is given explicitly, figsize is ignored.
     legend_kwds : dict (default None)
-        Keyword arguments to pass to matplotlib.pyplot.legend() or
-        matplotlib.pyplot.colorbar().
+        Keyword arguments to pass to :func:`matplotlib.pyplot.legend` or
+        :func:`matplotlib.pyplot.colorbar`.
         Additional accepted keywords when `scheme` is specified:
 
         fmt : string


Test patch:
Repository: geopandas/geopandas

Issue:
DOC: Address GeoPandas op deprecation in docs
While working on #2211 I noticed instances of the `op` parameter still being used.

This `op` parameter was deprecated in pull request #1626 in favour of `predicate`.

Locations where op is still present includes:
* [sjoin benchmark](https://github.com/geopandas/geopandas/blob/master/benchmarks/sjoin.py)
* [Spatial Joins notebook](https://github.com/geopandas/geopandas/blob/master/doc/source/gallery/spatial_joins.ipynb)
 
I can address the notebook instance but I don't know what the benchmark instance of `op` does so wouldn't want to change it without a thumbs up from a maintainer.


Discussion:
Good catch! You can simply replace every instance of `op` with `predicate` and it should work.

Resolving patch:
diff --git a/benchmarks/sjoin.py b/benchmarks/sjoin.py
--- a/benchmarks/sjoin.py
+++ b/benchmarks/sjoin.py
@@ -26,5 +26,5 @@ def setup(self, *args):
 
         self.df1, self.df2 = df1, df2
 
-    def time_sjoin(self, op):
-        sjoin(self.df1, self.df2, op=op)
+    def time_sjoin(self, predicate):
+        sjoin(self.df1, self.df2, predicate=predicate)


Test patch:
Repository: geopandas/geopandas

Issue:
DOC: `dissolve`: Document full capabilities of `aggfunc` argument
The documentation of `GeoDataFrame.dissolve` should clarify that `aggfunc` argument supports all the capabilities of 
Pandas [`DataFrame.agg`](geopandas.GeoDataFrame.dissolve).

These options are often quite useful, as one may want to produce multiple statistics per column, or different statistics for each column.

Currently, the [User Guide](https://geopandas.org/en/stable/docs/user_guide/aggregation_with_dissolve.html) only contains examples of passing a string to `aggfunc`. (It mentions that "it also accepts other summary statistic options as allowed by pandas.groupby", however the provided link to the `groupby` documentation isn't particularly useful.
It should also show the other options, and give an example.

The [API Reference](https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.dissolve.html#geopandas.GeoDataFrame.dissolve) states that `aggfunc` must be a function or string. It misses the option to pass a list or dictionary.
It should also show the other options




Discussion:

Resolving patch:
diff --git a/geopandas/geodataframe.py b/geopandas/geodataframe.py
--- a/geopandas/geodataframe.py
+++ b/geopandas/geodataframe.py
@@ -1476,6 +1476,11 @@ def dissolve(
         aggfunc : function or string, default "first"
             Aggregation function for manipulation of data associated
             with each group. Passed to pandas `groupby.agg` method.
+            Accepted combinations are:
+            - function
+            - string function name
+            - list of functions and/or function names, e.g. [np.sum, 'mean']
+            - dict of axis labels -> functions, function names or list of such.
         as_index : boolean, default True
             If true, groupby columns become index of result.
         level : int or str or sequence of int or sequence of str, default None


Test patch: