0

I've been trying to plot hatches (like this pattern, "//") on polygons of a shapefile, based on a condition. The condition is that whichever polygon values ("Sig") are greater than equal to 0.05, there should be a hatch pattern for them. Unfortunately the resulting map doesn't meet my requirements.

So I first plot the "AMOTL" variable and then wanted to plot the hatches (variable Sig) on top of them (if the values are greater than equal to 0.05). I have used the following code:

import contextily as ctx
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker
from matplotlib.patches import Ellipse, Polygon
data = gpd.read_file("mapsignif.shp")
Sig = data.loc[data["Sig"].ge(0.05)]
data.loc[data["AMOTL"].eq(0), "AMOTL"] = np.nan
ax = data.plot(
    figsize=(12, 10),
    column="AMOTL",
    legend=True,
    cmap="bwr",
    vmin = -1,
    vmax= 1,
    missing_kwds={"color":"white"},
)
Sig.plot(
    ax=ax,
    hatch='//'
)
map = Basemap(
    llcrnrlon=-50,
    llcrnrlat=30,
    urcrnrlon=50.0,
    urcrnrlat=85.0,
    resolution="i",
    lat_0=39.5,
    lon_0=1,
)
map.fillcontinents(color="lightgreen")
map.drawcoastlines()
map.drawparallels(np.arange(10,90,20),labels=[1,1,1,1])
map.drawmeridians(np.arange(-180,180,30),labels=[1,1,0,1])

Now the problem is that my original image (on which I want to plot the hatches) is different from the image resulting from the above code:

Original Image -

Original Image (on which I want to plot hatches)

Resultant image from above code: Resultant image from above code after assigning Sig

I basically want to plot hatches on that first image. This topic is similar to correlation plots where you have places with hatches (if the p-value is greater than 0.05). The first image plots the correlation variable and some of them are significant (defined by Sig). So I want to plot the Sig variable on top of the AMOTL. I've tried variations of the code, but still can't get through.

Would be grateful for some assistance... Here's my file - https://drive.google.com/file/d/10LPNjBtQMdQMw6XmXdJEg6Uq4icx_LD6/view?usp=sharing

Kee C
  • 5
  • 4
  • Please always include the [full traceback](//realpython.com/python-traceback) when asking about errors - it includes a lot of valuable information including which lines are erroring and why. – Michael Delgado Dec 14 '22 at 16:03
  • @MichaelDelgado I don't get any attribute errors after implementing your code, but I've run into another problem with the resulting images. Have edited the question above... – Kee C Dec 15 '22 at 07:39

1 Answers1

0

I’d bet this is the culprit:

data.loc[data["Sig"].ge(0.05), "Sig"].plot(
    column="Sig", hatch='//'
)

In this line, you’re selecting only the 'Sig' column, eliminating all spatial data in the 'geometry' column and returning a pandas.Series instead of a geopandas.GeoDataFrame. In order to plot a data column using the geometries column for your shapes you must maintain at least both of those columns in the object you call .plot on.

So instead, don’t select the column:

data.loc[data["Sig"].ge(0.05)].plot(
    column="Sig", hatch='//'
)

You are already telling geopandas to plot the "Sig" column by using the column argument to .plot - no need to limit the actual data too.

Also, when overlaying a plot on an existing axis, be sure to pass in the axis object:

data.loc[data["Sig"].ge(0.05)].plot(
    column="Sig", hatch='//', ax=ax
)
Michael Delgado
  • 13,789
  • 3
  • 29
  • 54
  • thank you for helping me understand this @Michael Delgado .. I've actually run into another problem. My original image and the end result are different... Is there some hold on function in python similar to Matlab? I've attached the images above for context.. – Kee C Dec 15 '22 at 07:43
  • Updated to mention passing in the existing axis. You can use all the same styling arguments as your first call. Note that this does completely redraw the second set of polygons - you’re not just adding hatching in the second call. Youll probably want to set a vmin and vmax on both plot calls or pass in a custom `norm` object to both so they render with the same color scale – Michael Delgado Dec 15 '22 at 15:51
  • I'm not quite sure I follow that.. What if I assign "Sig" and then plot it? So I did that, get close, but there's still an issue.. Updated the above since I cannot add full code here in comments @Michael Delgado – Kee C Dec 21 '22 at 04:42