0

I am trying to prevent the labels in the Northeast US map below from overlapping. I have tried to turn labels on and off for certain states in the region, but there definitely is a better way of doing it. Below is my code and output.

csv = pd.read_csv(r'C:\Downloads\Data.csv')
sf = r'C:\Downloads\s_11au16\s_11au16.shp'
US = gpd.read_file(sf)

#Merge them
data = gpd.GeoDataFrame(csv.merge(US))

#set projection
data = data.to_crs(epsg=6923)

#set up basemap
ax = data.plot(figsize = (12,8), column="soil_data", cmap="Greens", edgecolor='black', linewidth=.5, vmin=0, vmax=70, 
               missing_kwds={"color": "white", "edgecolor": "k", "label": "none"})
ax.set_title("Example", fontsize=18, fontweight='bold')
ax.set_axis_off()


#annotate data
label = data.dropna(subset='soil_data')
label.apply(lambda x: ax.annotate(text=int(x['soil_data']), xy=x.geometry.centroid.coords[0], color="black", 
                                  ha='center', fontsize=14, path_effects=[pe.withStroke(linewidth=3, 
                                                                                        foreground="white")]), axis=1)

Output map with overlapping labels in the Northeast US

Boone
  • 19
  • 6
  • Have you tried [adjustText](https://stackoverflow.com/questions/69522503/how-do-i-achieve-non-overlapping-text-with-matplotlib-without-changing-yticks)? – Tranbi Apr 06 '22 at 14:44
  • Yes @Tranbi, this was the first thing I tried. I am struggling with getting it to work. I keep getting an error "'str' object has no attribute 'get_position' ". I guess I'm just unfamiliar with where the adjustText would go in my function. – Boone Apr 06 '22 at 15:12

1 Answers1

2

Obviously I cannot test it without your data but if you're willing to try again with adjustText you could try replacing your label.apply(...) with something like that:

texts = []
for i, row in label.iterrows(): 
  texts.append(ax.annotate(text=int(row['soil_data']), xy=row.geometry.centroid.coords[0], color="black", 
                                  ha='center', fontsize=14, path_effects=[pe.withStroke(linewidth=3, 
                                                                                        foreground="white")]))

adjust_text(texts)

I don't know how adjust_text deals with annotations, so if this doesn't work, you could try converting it to plt.text.

(The matplotlib class Annotation inherits from the Text class)

Tranbi
  • 11,407
  • 6
  • 16
  • 33