Repository: geopandas/geopandas

Issue:
Failing tests for sjoin(... how='right', op='within') on pandas master
Tests for `sjoin` are failing with pandas master (https://travis-ci.org/github/geopandas/geopandas/jobs/673491281) it we do `sjoin(... how='right', op='within')`. However, it seems to me that the change in pandas is actually fix of incorrect behaviour. Consider following example from our tests:

```py
polys1 = GeoSeries(
    [
        Polygon([(0, 0), (5, 0), (5, 5), (0, 5)]),
        Polygon([(5, 5), (6, 5), (6, 6), (5, 6)]),
        Polygon([(6, 0), (9, 0), (9, 3), (6, 3)]),
    ]
)

polys2 = GeoSeries(
    [
        Polygon([(1, 1), (4, 1), (4, 4), (1, 4)]),
        Polygon([(4, 4), (7, 4), (7, 7), (4, 7)]),
        Polygon([(7, 7), (10, 7), (10, 10), (7, 10)]),
    ]
)

df1 = GeoDataFrame({"geometry": polys1, "df1": [0, 1, 2]})
df2 = GeoDataFrame({"geometry": polys2, "df2": [3, 4, 5]})
df1.index = ["a", "b", "c"]
df2.index = ["d", "e", "f"]
```

With pandas 1.0.3, the result of `res = sjoin(df1, df2, how="right", op='within')` is 

```
  index_left  df1                                           geometry  df2
e          b  1.0  POLYGON ((4.00000 4.00000, 7.00000 4.00000, 7....    4
d        NaN  NaN  POLYGON ((1.00000 1.00000, 4.00000 1.00000, 4....    3
f        NaN  NaN  POLYGON ((7.00000 7.00000, 10.00000 7.00000, 1...    5
```

which means that the order of original df has been altered. Behaviour with pandas master is this:

```
  index_left  df1                                           geometry  df2
d        NaN  NaN  POLYGON ((1.00000 1.00000, 4.00000 1.00000, 4....    3
e          b  1.0  POLYGON ((4.00000 4.00000, 7.00000 4.00000, 7....    4
f        NaN  NaN  POLYGON ((7.00000 7.00000, 10.00000 7.00000, 1...    5
```
The order of rows remains the same as is in the original df. 

Ideally we should return the same result (I would say the new one) for all versions of pandas we support.




Discussion:

Patch:
diff --git a/doc/source/mergingdata.rst b/doc/source/mergingdata.rst
index 3bfddeb3..7c5daf05 100644
--- a/doc/source/mergingdata.rst
+++ b/doc/source/mergingdata.rst
@@ -13,7 +13,7 @@ There are two ways to combine datasets in *geopandas* -- attribute joins and spa
 
 In an attribute join, a ``GeoSeries`` or ``GeoDataFrame`` is combined with a regular *pandas* ``Series`` or ``DataFrame`` based on a common variable. This is analogous to normal merging or joining in *pandas*.
 
-In a Spatial Join, observations from to ``GeoSeries`` or ``GeoDataFrames`` are combined based on their spatial relationship to one another.
+In a Spatial Join, observations from two ``GeoSeries`` or ``GeoDataFrames`` are combined based on their spatial relationship to one another.
 
 In the following examples, we use these datasets:
 
@@ -31,6 +31,22 @@ In the following examples, we use these datasets:
    countries = countries.rename(columns={'name':'country'})
 
 
+Appending
+---------
+
+Appending GeoDataFrames and GeoSeries uses pandas ``append`` methods. Keep in mind, that appended geometry columns needs to have the same CRS.
+
+.. ipython:: python
+
+    # Appending GeoSeries
+    joined = world.geometry.append(cities.geometry)
+
+    # Appending GeoDataFrames
+    europe = world[world.continent == 'Europe']
+    asia = world[world.continent == 'Asia']
+    eurasia = europe.append(asia)
+
+
 Attribute Joins
 ----------------
 
@@ -116,5 +132,3 @@ Existing spatial indexes on either `left_df` or `right_df` will be reused when p
     # sindex for df1 is reused
     sjoin(df1, df3, ...)
     # sindex for df1 is reused again
-
-
diff --git a/geopandas/geodataframe.py b/geopandas/geodataframe.py
index c5c3ec8d..cfb7e739 100644
--- a/geopandas/geodataframe.py
+++ b/geopandas/geodataframe.py
@@ -6,6 +6,8 @@ import pandas as pd
 from pandas import DataFrame, Series
 
 from shapely.geometry import mapping, shape
+from shapely.geometry.base import BaseGeometry
+
 
 from pyproj import CRS
 
@@ -684,6 +686,8 @@ class GeoDataFrame(GeoPandasBase, DataFrame):
         df['geometry'] = [geom... for geom in df.geometry]
         """
         if not pd.api.types.is_list_like(key) and key == self._geometry_column_name:
+            if pd.api.types.is_scalar(value) or isinstance(value, BaseGeometry):
+                value = [value] * self.shape[0]
             try:
                 value = _ensure_geometry(value, crs=self.crs)
             except TypeError:
@@ -870,6 +874,26 @@ class GeoDataFrame(GeoPandasBase, DataFrame):
         # do not return a GeoDataFrame
         return pd.DataFrame(df)
 
+        #
+        # Implement standard operators for GeoSeries
+        #
+
+    def __xor__(self, other):
+        """Implement ^ operator as for builtin set type"""
+        return self.geometry.symmetric_difference(other)
+
+    def __or__(self, other):
+        """Implement | operator as for builtin set type"""
+        return self.geometry.union(other)
+
+    def __and__(self, other):
+        """Implement & operator as for builtin set type"""
+        return self.geometry.intersection(other)
+
+    def __sub__(self, other):
+        """Implement - operator as for builtin set type"""
+        return self.geometry.difference(other)
+
 
 def _dataframe_set_geometry(self, col, drop=False, inplace=False, crs=None):
     if inplace:
diff --git a/geopandas/plotting.py b/geopandas/plotting.py
index f915a569..6b0b096d 100644
--- a/geopandas/plotting.py
+++ b/geopandas/plotting.py
@@ -6,6 +6,21 @@ import pandas as pd
 import geopandas
 
 
+def deprecated(new):
+    """Helper to provide deprecation warning."""
+
+    def old(*args, **kwargs):
+        warnings.warn(
+            "{} is intended for internal ".format(new.__name__[1:])
+            + "use only, and will be deprecated.",
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        new(*args, **kwargs)
+
+    return old
+
+
 def _flatten_multi_geoms(geoms, prefix="Multi"):
     """
     Returns Series like geoms and index, except that any Multi geometries
@@ -17,7 +32,6 @@ def _flatten_multi_geoms(geoms, prefix="Multi"):
 
     Returns
     -------
-
     components : list of geometry
 
     component_index : index array
@@ -40,7 +54,7 @@ def _flatten_multi_geoms(geoms, prefix="Multi"):
     return components, np.array(component_index)
 
 
-def plot_polygon_collection(
+def _plot_polygon_collection(
     ax, geoms, values=None, color=None, cmap=None, vmin=None, vmax=None, **kwargs
 ):
     """
@@ -48,32 +62,25 @@ def plot_polygon_collection(
 
     Parameters
     ----------
-
     ax : matplotlib.axes.Axes
         where shapes will be plotted
-
     geoms : a sequence of `N` Polygons and/or MultiPolygons (can be mixed)
 
     values : a sequence of `N` values, optional
         Values will be mapped to colors using vmin/vmax/cmap. They should
         have 1:1 correspondence with the geometries (not their components).
         Otherwise follows `color` / `facecolor` kwargs.
-
     edgecolor : single color or sequence of `N` colors
         Color for the edge of the polygons
-
     facecolor : single color or sequence of `N` colors
         Color to fill the polygons. Cannot be used together with `values`.
-
     color : single color or sequence of `N` colors
         Sets both `edgecolor` and `facecolor`
-
     **kwargs
         Additional keyword arguments passed to the collection
 
     Returns
     -------
-
     collection : matplotlib.collections.Collection that was plotted
     """
 
@@ -130,7 +137,10 @@ def plot_polygon_collection(
     return collection
 
 
-def plot_linestring_collection(
+plot_polygon_collection = deprecated(_plot_polygon_collection)
+
+
+def _plot_linestring_collection(
     ax, geoms, values=None, color=None, cmap=None, vmin=None, vmax=None, **kwargs
 ):
     """
@@ -138,25 +148,19 @@ def plot_linestring_collection(
 
     Parameters
     ----------
-
     ax : matplotlib.axes.Axes
         where shapes will be plotted
-
     geoms : a sequence of `N` LineStrings and/or MultiLineStrings (can be
             mixed)
-
     values : a sequence of `N` values, optional
         Values will be mapped to colors using vmin/vmax/cmap. They should
         have 1:1 correspondence with the geometries (not their components).
-
     color : single color or sequence of `N` colors
         Cannot be used together with `values`.
 
     Returns
     -------
-
     collection : matplotlib.collections.Collection that was plotted
-
     """
     from matplotlib.collections import LineCollection
     from matplotlib.colors import is_color_like
@@ -194,7 +198,10 @@ def plot_linestring_collection(
     return collection
 
 
-def plot_point_collection(
+plot_linestring_collection = deprecated(_plot_linestring_collection)
+
+
+def _plot_point_collection(
     ax,
     geoms,
     values=None,
@@ -264,6 +271,9 @@ def plot_point_collection(
     return collection
 
 
+plot_point_collection = deprecated(_plot_point_collection)
+
+
 def plot_series(s, cmap=None, color=None, ax=None, figsize=None, **style_kwds):
     """
     Plot a GeoSeries.
@@ -369,7 +379,7 @@ def plot_series(s, cmap=None, color=None, ax=None, figsize=None, **style_kwds):
             facecolor = color
 
         values_ = values[poly_idx] if cmap else None
-        plot_polygon_collection(
+        _plot_polygon_collection(
             ax, polys, values_, facecolor=facecolor, cmap=cmap, **style_kwds
         )
 
@@ -377,7 +387,7 @@ def plot_series(s, cmap=None, color=None, ax=None, figsize=None, **style_kwds):
     lines = expl_series[line_idx]
     if not lines.empty:
         values_ = values[line_idx] if cmap else None
-        plot_linestring_collection(
+        _plot_linestring_collection(
             ax, lines, values_, color=color, cmap=cmap, **style_kwds
         )
 
@@ -385,7 +395,9 @@ def plot_series(s, cmap=None, color=None, ax=None, figsize=None, **style_kwds):
     points = expl_series[point_idx]
     if not points.empty:
         values_ = values[point_idx] if cmap else None
-        plot_point_collection(ax, points, values_, color=color, cmap=cmap, **style_kwds)
+        _plot_point_collection(
+            ax, points, values_, color=color, cmap=cmap, **style_kwds
+        )
 
     plt.draw()
     return ax
@@ -616,7 +628,7 @@ def plot_dataframe(
     polys = expl_series[poly_idx & np.invert(nan_idx)]
     subset = values[poly_idx & np.invert(nan_idx)]
     if not polys.empty:
-        plot_polygon_collection(
+        _plot_polygon_collection(
             ax, polys, subset, vmin=mn, vmax=mx, cmap=cmap, **style_kwds
         )
 
@@ -624,7 +636,7 @@ def plot_dataframe(
     lines = expl_series[line_idx & np.invert(nan_idx)]
     subset = values[line_idx & np.invert(nan_idx)]
     if not lines.empty:
-        plot_linestring_collection(
+        _plot_linestring_collection(
             ax, lines, subset, vmin=mn, vmax=mx, cmap=cmap, **style_kwds
         )
 
@@ -635,7 +647,7 @@ def plot_dataframe(
         if isinstance(markersize, np.ndarray):
             markersize = np.take(markersize, multiindex, axis=0)
             markersize = markersize[point_idx & np.invert(nan_idx)]
-        plot_point_collection(
+        _plot_point_collection(
             ax,
             points,
             subset,
@@ -746,7 +758,6 @@ def _mapclassify_choro(values, scheme, **classification_kwds):
     binning
         Binning objects that holds the Series with values replaced with
         class identifier and the bins.
-
     """
     try:
         import mapclassify.classifiers as classifiers
diff --git a/geopandas/tools/overlay.py b/geopandas/tools/overlay.py
index 8d0b7c43..0ae02ed0 100644
--- a/geopandas/tools/overlay.py
+++ b/geopandas/tools/overlay.py
@@ -139,16 +139,17 @@ def _overlay_union(df1, df2):
 
 
 def overlay(df1, df2, how="intersection", make_valid=True, keep_geom_type=True):
-    """Perform spatial overlay between two polygons.
+    """Perform spatial overlay between two GeoDataFrames.
 
-    Currently only supports data GeoDataFrames with polygons.
-    Implements several methods that are all effectively subsets of
-    the union.
+    Currently only supports data GeoDataFrames with uniform geometry types,
+    i.e. containing only (Multi)Polygons, or only (Multi)Points, or a
+    combination of (Multi)LineString and LinearRing shapes.
+    Implements several methods that are all effectively subsets of the union.
 
     Parameters
     ----------
-    df1 : GeoDataFrame with MultiPolygon or Polygon geometry column
-    df2 : GeoDataFrame with MultiPolygon or Polygon geometry column
+    df1 : GeoDataFrame
+    df2 : GeoDataFrame
     how : string
         Method of spatial overlay: 'intersection', 'union',
         'identity', 'symmetric_difference' or 'difference'.


Test patch:
diff --git a/geopandas/tests/test_crs.py b/geopandas/tests/test_crs.py
index 088cc37b..6acfa6d0 100644
--- a/geopandas/tests/test_crs.py
+++ b/geopandas/tests/test_crs.py
@@ -6,7 +6,7 @@ import random
 import numpy as np
 import pandas as pd
 
-from shapely.geometry import Point, Polygon
+from shapely.geometry import Point, Polygon, LineString
 import pyproj
 
 from geopandas import GeoSeries, GeoDataFrame, points_from_xy, datasets, read_file
@@ -282,6 +282,18 @@ class TestGeometryArrayCRS:
         df.crs = 27700
         assert df.crs == self.osgb
 
+    @pytest.mark.parametrize(
+        "scalar", [None, Point(0, 0), LineString([(0, 0), (1, 1)])]
+    )
+    def test_scalar(self, scalar):
+        with pytest.warns(FutureWarning):
+            df = GeoDataFrame()
+            df.crs = 4326
+        df["geometry"] = scalar
+        assert df.crs == self.wgs
+        assert df.geometry.crs == self.wgs
+        assert df.geometry.values.crs == self.wgs
+
     def test_read_file(self):
         nybb_filename = datasets.get_path("nybb")
         df = read_file(nybb_filename)
diff --git a/geopandas/tests/test_geom_methods.py b/geopandas/tests/test_geom_methods.py
index d5fdf941..f3bd4592 100644
--- a/geopandas/tests/test_geom_methods.py
+++ b/geopandas/tests/test_geom_methods.py
@@ -83,6 +83,9 @@ class TestGeomMethods:
         self.gdf2 = GeoDataFrame(
             {"geometry": self.g1, "col3": [4, 5], "col4": ["rand", "string"]}
         )
+        self.gdf3 = GeoDataFrame(
+            {"geometry": self.g3, "col3": [4, 5], "col4": ["rand", "string"]}
+        )
 
     def _test_unary_real(self, op, expected, a):
         """ Tests for 'area', 'length', 'is_valid', etc. """
@@ -123,6 +126,7 @@ class TestGeomMethods:
         """
         The operators only have GeoSeries on the left, but can have
         GeoSeries or GeoDataFrame on the right.
+        If GeoDataFrame is on the left, geometry column is used.
 
         """
         if isinstance(expected, GeoPandasBase):
@@ -655,25 +659,29 @@ class TestGeomMethods:
 
     #
     # Test '&', '|', '^', and '-'
-    # The left can only be a GeoSeries. The right hand side can be a
-    # GeoSeries, GeoDataFrame or Shapely geometry
     #
     def test_intersection_operator(self):
         self._test_binary_operator("__and__", self.t1, self.g1, self.g2)
+        self._test_binary_operator("__and__", self.t1, self.gdf1, self.g2)
 
     def test_union_operator(self):
         self._test_binary_operator("__or__", self.sq, self.g1, self.g2)
+        self._test_binary_operator("__or__", self.sq, self.gdf1, self.g2)
 
     def test_union_operator_polygon(self):
         self._test_binary_operator("__or__", self.sq, self.g1, self.t2)
+        self._test_binary_operator("__or__", self.sq, self.gdf1, self.t2)
 
     def test_symmetric_difference_operator(self):
         self._test_binary_operator("__xor__", self.sq, self.g3, self.g4)
+        self._test_binary_operator("__xor__", self.sq, self.gdf3, self.g4)
 
     def test_difference_series2(self):
         expected = GeoSeries([GeometryCollection(), self.t2])
         self._test_binary_operator("__sub__", expected, self.g1, self.g2)
+        self._test_binary_operator("__sub__", expected, self.gdf1, self.g2)
 
     def test_difference_poly2(self):
         expected = GeoSeries([self.t1, self.t1])
         self._test_binary_operator("__sub__", expected, self.g1, self.t2)
+        self._test_binary_operator("__sub__", expected, self.gdf1, self.t2)
diff --git a/geopandas/tests/test_plotting.py b/geopandas/tests/test_plotting.py
index 306e3b6c..5ffacf1c 100644
--- a/geopandas/tests/test_plotting.py
+++ b/geopandas/tests/test_plotting.py
@@ -744,40 +744,40 @@ class TestPlotCollections:
         # failing with matplotlib 1.4.3 (edge stays black even when specified)
         pytest.importorskip("matplotlib", "1.5.0")
 
-        from geopandas.plotting import plot_point_collection
+        from geopandas.plotting import _plot_point_collection, plot_point_collection
         from matplotlib.collections import PathCollection
 
         fig, ax = plt.subplots()
-        coll = plot_point_collection(ax, self.points)
+        coll = _plot_point_collection(ax, self.points)
         assert isinstance(coll, PathCollection)
         ax.cla()
 
         # default: single default matplotlib color
-        coll = plot_point_collection(ax, self.points)
+        coll = _plot_point_collection(ax, self.points)
         _check_colors(self.N, coll.get_facecolors(), [MPL_DFT_COLOR] * self.N)
         # edgecolor depends on matplotlib version
         # _check_colors(self.N, coll.get_edgecolors(), [MPL_DFT_COLOR]*self.N)
         ax.cla()
 
         # specify single other color
-        coll = plot_point_collection(ax, self.points, color="g")
+        coll = _plot_point_collection(ax, self.points, color="g")
         _check_colors(self.N, coll.get_facecolors(), ["g"] * self.N)
         _check_colors(self.N, coll.get_edgecolors(), ["g"] * self.N)
         ax.cla()
 
         # specify edgecolor/facecolor
-        coll = plot_point_collection(ax, self.points, facecolor="g", edgecolor="r")
+        coll = _plot_point_collection(ax, self.points, facecolor="g", edgecolor="r")
         _check_colors(self.N, coll.get_facecolors(), ["g"] * self.N)
         _check_colors(self.N, coll.get_edgecolors(), ["r"] * self.N)
         ax.cla()
 
         # list of colors
-        coll = plot_point_collection(ax, self.points, color=["r", "g", "b"])
+        coll = _plot_point_collection(ax, self.points, color=["r", "g", "b"])
         _check_colors(self.N, coll.get_facecolors(), ["r", "g", "b"])
         _check_colors(self.N, coll.get_edgecolors(), ["r", "g", "b"])
         ax.cla()
 
-        coll = plot_point_collection(
+        coll = _plot_point_collection(
             ax,
             self.points,
             color=[(0.5, 0.5, 0.5, 0.5), (0.1, 0.2, 0.3, 0.5), (0.4, 0.5, 0.6, 0.5)],
@@ -796,14 +796,18 @@ class TestPlotCollections:
 
         # not a color
         with pytest.raises(TypeError):
-            plot_point_collection(ax, self.points, color="not color")
+            _plot_point_collection(ax, self.points, color="not color")
+
+        # check DeprecationWarning
+        with pytest.warns(DeprecationWarning):
+            plot_point_collection(ax, self.points)
 
     def test_points_values(self):
-        from geopandas.plotting import plot_point_collection
+        from geopandas.plotting import _plot_point_collection
 
         # default colormap
         fig, ax = plt.subplots()
-        coll = plot_point_collection(ax, self.points, self.values)
+        coll = _plot_point_collection(ax, self.points, self.values)
         fig.canvas.draw_idle()
         cmap = plt.get_cmap()
         expected_colors = cmap(np.arange(self.N) / (self.N - 1))
@@ -812,36 +816,39 @@ class TestPlotCollections:
         # _check_colors(self.N, coll.get_edgecolors(), expected_colors)
 
     def test_linestrings(self):
-        from geopandas.plotting import plot_linestring_collection
+        from geopandas.plotting import (
+            _plot_linestring_collection,
+            plot_linestring_collection,
+        )
         from matplotlib.collections import LineCollection
 
         fig, ax = plt.subplots()
-        coll = plot_linestring_collection(ax, self.lines)
+        coll = _plot_linestring_collection(ax, self.lines)
         assert isinstance(coll, LineCollection)
         ax.cla()
 
         # default: single default matplotlib color
-        coll = plot_linestring_collection(ax, self.lines)
+        coll = _plot_linestring_collection(ax, self.lines)
         _check_colors(self.N, coll.get_color(), [MPL_DFT_COLOR] * self.N)
         ax.cla()
 
         # specify single other color
-        coll = plot_linestring_collection(ax, self.lines, color="g")
+        coll = _plot_linestring_collection(ax, self.lines, color="g")
         _check_colors(self.N, coll.get_colors(), ["g"] * self.N)
         ax.cla()
 
         # specify edgecolor / facecolor
-        coll = plot_linestring_collection(ax, self.lines, facecolor="g", edgecolor="r")
+        coll = _plot_linestring_collection(ax, self.lines, facecolor="g", edgecolor="r")
         _check_colors(self.N, coll.get_facecolors(), ["g"] * self.N)
         _check_colors(self.N, coll.get_edgecolors(), ["r"] * self.N)
         ax.cla()
 
         # list of colors
-        coll = plot_linestring_collection(ax, self.lines, color=["r", "g", "b"])
+        coll = _plot_linestring_collection(ax, self.lines, color=["r", "g", "b"])
         _check_colors(self.N, coll.get_colors(), ["r", "g", "b"])
         ax.cla()
 
-        coll = plot_linestring_collection(
+        coll = _plot_linestring_collection(
             ax,
             self.lines,
             color=[(0.5, 0.5, 0.5, 0.5), (0.1, 0.2, 0.3, 0.5), (0.4, 0.5, 0.6, 0.5)],
@@ -854,7 +861,7 @@ class TestPlotCollections:
         ax.cla()
 
         # pass through of kwargs
-        coll = plot_linestring_collection(ax, self.lines, linestyle="--", linewidth=1)
+        coll = _plot_linestring_collection(ax, self.lines, linestyle="--", linewidth=1)
         exp_ls = _style_to_linestring_onoffseq("dashed", 1)
         res_ls = coll.get_linestyle()[0]
         assert res_ls[0] == exp_ls[0]
@@ -863,15 +870,19 @@ class TestPlotCollections:
 
         # not a color
         with pytest.raises(TypeError):
-            plot_linestring_collection(ax, self.lines, color="not color")
+            _plot_linestring_collection(ax, self.lines, color="not color")
+
+        # check DeprecationWarning
+        with pytest.warns(DeprecationWarning):
+            plot_linestring_collection(ax, self.lines)
 
     def test_linestrings_values(self):
-        from geopandas.plotting import plot_linestring_collection
+        from geopandas.plotting import _plot_linestring_collection
 
         fig, ax = plt.subplots()
 
         # default colormap
-        coll = plot_linestring_collection(ax, self.lines, self.values)
+        coll = _plot_linestring_collection(ax, self.lines, self.values)
         fig.canvas.draw_idle()
         cmap = plt.get_cmap()
         expected_colors = cmap(np.arange(self.N) / (self.N - 1))
@@ -879,7 +890,7 @@ class TestPlotCollections:
         ax.cla()
 
         # specify colormap
-        coll = plot_linestring_collection(ax, self.lines, self.values, cmap="RdBu")
+        coll = _plot_linestring_collection(ax, self.lines, self.values, cmap="RdBu")
         fig.canvas.draw_idle()
         cmap = plt.get_cmap("RdBu")
         expected_colors = cmap(np.arange(self.N) / (self.N - 1))
@@ -887,7 +898,7 @@ class TestPlotCollections:
         ax.cla()
 
         # specify vmin/vmax
-        coll = plot_linestring_collection(ax, self.lines, self.values, vmin=3, vmax=5)
+        coll = _plot_linestring_collection(ax, self.lines, self.values, vmin=3, vmax=5)
         fig.canvas.draw_idle()
         cmap = plt.get_cmap()
         expected_colors = cmap([0])
@@ -895,33 +906,33 @@ class TestPlotCollections:
         ax.cla()
 
     def test_polygons(self):
-        from geopandas.plotting import plot_polygon_collection
+        from geopandas.plotting import _plot_polygon_collection, plot_polygon_collection
         from matplotlib.collections import PatchCollection
 
         fig, ax = plt.subplots()
-        coll = plot_polygon_collection(ax, self.polygons)
+        coll = _plot_polygon_collection(ax, self.polygons)
         assert isinstance(coll, PatchCollection)
         ax.cla()
 
         # default: single default matplotlib color
-        coll = plot_polygon_collection(ax, self.polygons)
+        coll = _plot_polygon_collection(ax, self.polygons)
         _check_colors(self.N, coll.get_facecolor(), [MPL_DFT_COLOR] * self.N)
         _check_colors(self.N, coll.get_edgecolor(), ["k"] * self.N)
         ax.cla()
 
         # default: color sets both facecolor and edgecolor
-        coll = plot_polygon_collection(ax, self.polygons, color="g")
+        coll = _plot_polygon_collection(ax, self.polygons, color="g")
         _check_colors(self.N, coll.get_facecolor(), ["g"] * self.N)
         _check_colors(self.N, coll.get_edgecolor(), ["g"] * self.N)
         ax.cla()
 
         # default: color can be passed as a list
-        coll = plot_polygon_collection(ax, self.polygons, color=["g", "b", "r"])
+        coll = _plot_polygon_collection(ax, self.polygons, color=["g", "b", "r"])
         _check_colors(self.N, coll.get_facecolor(), ["g", "b", "r"])
         _check_colors(self.N, coll.get_edgecolor(), ["g", "b", "r"])
         ax.cla()
 
-        coll = plot_polygon_collection(
+        coll = _plot_polygon_collection(
             ax,
             self.polygons,
             color=[(0.5, 0.5, 0.5, 0.5), (0.1, 0.2, 0.3, 0.5), (0.4, 0.5, 0.6, 0.5)],
@@ -939,28 +950,31 @@ class TestPlotCollections:
         ax.cla()
 
         # only setting facecolor keeps default for edgecolor
-        coll = plot_polygon_collection(ax, self.polygons, facecolor="g")
+        coll = _plot_polygon_collection(ax, self.polygons, facecolor="g")
         _check_colors(self.N, coll.get_facecolor(), ["g"] * self.N)
         _check_colors(self.N, coll.get_edgecolor(), ["k"] * self.N)
         ax.cla()
 
         # custom facecolor and edgecolor
-        coll = plot_polygon_collection(ax, self.polygons, facecolor="g", edgecolor="r")
+        coll = _plot_polygon_collection(ax, self.polygons, facecolor="g", edgecolor="r")
         _check_colors(self.N, coll.get_facecolor(), ["g"] * self.N)
         _check_colors(self.N, coll.get_edgecolor(), ["r"] * self.N)
         ax.cla()
 
         # not a color
         with pytest.raises(TypeError):
-            plot_polygon_collection(ax, self.polygons, color="not color")
+            _plot_polygon_collection(ax, self.polygons, color="not color")
+        # check DeprecationWarning
+        with pytest.warns(DeprecationWarning):
+            plot_polygon_collection(ax, self.polygons)
 
     def test_polygons_values(self):
-        from geopandas.plotting import plot_polygon_collection
+        from geopandas.plotting import _plot_polygon_collection
 
         fig, ax = plt.subplots()
 
         # default colormap, edge is still black by default
-        coll = plot_polygon_collection(ax, self.polygons, self.values)
+        coll = _plot_polygon_collection(ax, self.polygons, self.values)
         fig.canvas.draw_idle()
         cmap = plt.get_cmap()
         exp_colors = cmap(np.arange(self.N) / (self.N - 1))
@@ -970,7 +984,7 @@ class TestPlotCollections:
         ax.cla()
 
         # specify colormap
-        coll = plot_polygon_collection(ax, self.polygons, self.values, cmap="RdBu")
+        coll = _plot_polygon_collection(ax, self.polygons, self.values, cmap="RdBu")
         fig.canvas.draw_idle()
         cmap = plt.get_cmap("RdBu")
         exp_colors = cmap(np.arange(self.N) / (self.N - 1))
@@ -978,7 +992,7 @@ class TestPlotCollections:
         ax.cla()
 
         # specify vmin/vmax
-        coll = plot_polygon_collection(ax, self.polygons, self.values, vmin=3, vmax=5)
+        coll = _plot_polygon_collection(ax, self.polygons, self.values, vmin=3, vmax=5)
         fig.canvas.draw_idle()
         cmap = plt.get_cmap()
         exp_colors = cmap([0])
@@ -986,7 +1000,7 @@ class TestPlotCollections:
         ax.cla()
 
         # override edgecolor
-        coll = plot_polygon_collection(ax, self.polygons, self.values, edgecolor="g")
+        coll = _plot_polygon_collection(ax, self.polygons, self.values, edgecolor="g")
         fig.canvas.draw_idle()
         cmap = plt.get_cmap()
         exp_colors = cmap(np.arange(self.N) / (self.N - 1))
diff --git a/geopandas/tools/tests/test_sjoin.py b/geopandas/tools/tests/test_sjoin.py
index 168f8983..beb5fb5b 100644
--- a/geopandas/tools/tests/test_sjoin.py
+++ b/geopandas/tools/tests/test_sjoin.py
@@ -1,3 +1,5 @@
+from distutils.version import LooseVersion
+
 import numpy as np
 import pandas as pd
 
@@ -288,6 +290,10 @@ class TestSpatialJoin:
             )
             exp.index.names = df2.index.names
 
+        # GH 1364 fix of behaviour was done in pandas 1.1.0
+        if op == "within" and str(pd.__version__) >= LooseVersion("1.1.0"):
+            exp = exp.sort_index()
+
         assert_frame_equal(res, exp, check_index_type=False)