0

I am trying to iterate through matplotlib subplots based on index, and it works fine for fig, axs = plt.subplots(4, 1), but it throws and error AttributeError: 'numpy.ndarray' object has no attribute 'set_aspect' for fig, axs = plt.subplots(2, 2). Using Matplotlib version 3.2.1.

Here is an example setup. I have a dataframe of coordinates that represent polygons and they have categories like A,B,C, etc. I want to plot the polygons in various combinations (i.e., plot A and B on one plot, A and C on another plot, etc.) so I have these combinations defined in a dictionary. Then, I set up my subplots equal to the number of dictionary items, loop through the dictionary, and use the dictionary index number as the subplot index number.

import pandas as pd
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely import geometry
%matplotlib inline 

df = pd.DataFrame(
    {
    "x1": [8.6,13.5,18.7,50.8,45.2,41.8,12.8,13.8,19.7,],
    "y1": [81.4,76.7,68.8,54.5,50.8,44.1,19.8,15.3,13.3,],
    "x2": [15.6,21.0,22.4,53.4,50.6,49.5,16.9,17.2,20.3,],
    "y2": [82.2,76.2,74.0,53.0,49.5,43.1,21.1,18.4,20.3,],
    "cat": ["A","A","A","B","B","B","C","C","C",],
    }
)

display(df)

enter image description here

dict_combinations = {
    "var1": ["A",],
    "var2": ["A","B",],
    "var3": ["B","C",],
    "var4": ["A","C",],
}

This plotting works, using fig, axs = plt.subplots(4, 1):

fig, axs = plt.subplots(4, 1)

for index, (key, value) in enumerate(dict_combinations.items()):
    df2 =  df[df['cat'].isin(value)].copy()
    for name, group in df2.groupby('cat'):
        group = group.copy()
        top = group[["x1", "y1"]].copy().rename(columns={"x1": "x", "y1": "y"})
        bot = group[["x2", "y2"]].copy().rename(columns={"x2": "x", "y2": "y"})
        bot = bot[::-1]
        df3 = pd.concat([top, bot])
        poly = geometry.Polygon(df3.values.tolist())
        poly = gpd.GeoDataFrame([poly], columns={"geometry"}, crs="EPSG:4326")
        poly.plot(ax=axs[index])

enter image description here

Changing fig, axs = plt.subplots(4, 1) to fig, axs = plt.subplots(2, 2) throws an error (AttributeError: 'numpy.ndarray' object has no attribute 'set_aspect'). How can I fix this?

a11
  • 3,122
  • 4
  • 27
  • 66
  • From the linked thread: "`axes` is then an array of `n` rows and `m` columns. One could then iterate over the rows and columns independently, or over the flattened version of the `axes` array" – BigBen Dec 10 '21 at 20:40
  • @BigBen I am not sure how to incorporate flatten into my loop, and I still don't understand why it works for (4,1) and (1.4) but not (2,2) – a11 Dec 10 '21 at 20:42
  • 3
    The difference is that when you stack subplots in two directions, a 2D array is returned instead of a 1D array: see [the docs](https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subplots_demo.html). This has been asked and answered in many different formats on this site. – BigBen Dec 10 '21 at 20:45
  • 2
    `fig, axs = plt.subplots(2, 2)` and then `axs = axs.flatten()` should work for your example code. By the way, it is highly recommended upgrading your matplotlib version. Developers have been working really hard and added many thousands of corrections, improvements and extensions to the code. – JohanC Dec 10 '21 at 22:28

0 Answers0