фасетирование в цикле - присвоение оси df.plot оси

Основываясь на данных из этого вопроса о фасетировании через цикл, мне было интересно, возможно ли это вызвать ax = df.plot(kind='bar') и назначить сгенерированный таким образом объект AxesSubplot определенной позиции / координате оси? (например, фасетная строка 1, столбец 1, 2, 3 и т. д.)?

Причина, по которой я спрашиваю, на самом деле не в том, чтобы фасетировать гистограммы как таковые, а в том, чтобы создать карту фасетов с использованием библиотеки geopandas. Если он работал с гистограммами, он также мог работать с вызовами geopandas geodataframe.plot (). Я не могу построить карту из самих осей, поэтому мне кажется, что мне нужно пойти другим путем - получить оси как побочный продукт вызова сюжета, а затем поместить их в сетку.

Нерабочий пример - цикл здесь действительно псевдо; Я не перемещаю индекс оси для построения новой панели каждый раз (фактически, я перезаписываю объект осей из вызова подзаголовков). Тем не менее, это то, что я хотел бы сделать - сопоставить объект оси, созданный из вызова графика, с осями (координатное пространство) из вызова подзаголовков).

N = 100
industry = ['a','b','c']
city = ['x','y','z']
ind = np.random.choice(industry, N)
cty = np.random.choice(city, N)
jobs = np.random.randint(low=1,high=250,size=N)
df_city =pd.DataFrame({'industry':ind,'city':cty,'jobs':jobs})

## how many panels do we need?
cols =df_city.city.value_counts().shape[0]
fig, axes = plt.subplots(1, cols, figsize=(8, 8))

for x, city in enumerate(df_city.city.value_counts().index.values):
    data = df_city[(df_city['city'] == city)]
    data = data.groupby(['industry']).jobs.sum()
    axes = data.plot(kind='bar')
    print type(axes)
    fig.suptitle('Employment By Industry By City', fontsize=20)

<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.AxesSubplot'>
<class 'matplotlib.axes._subplots.AxesSubplot'>

введите описание изображения здесь


person ako    schedule 06.10.2014    source источник


Ответы (1)


Если я правильно понимаю, принятый ответ в этом другом вопросе чрезмерно пессимистичен в отношении шансов сделать это с пандами. Как насчет этого:

for ix, (key, group) in enumerate(df_city.groupby('industry')):
    ax = pyplot.subplot(1, 3, ix+1)
    group.groupby('city')['jobs'].sum().plot(kind='bar', ax=ax)
    ax.set_xlabel('industry: {}'.format(key))

При этом вы получаете:

введите описание изображения здесь

Идея состоит в том, чтобы сгруппировать по переменной, которую вы хотите разделить на подзаголовки, и перебрать группы. Для каждой группы используйте pyplot.subplot, чтобы нацелить желаемый подзаголовок для каждой группы, и используйте другую groupby для данных группы, чтобы получить итоговые значения для построения графика. Вы можете передать аргумент ax в DataFrame.plot, чтобы он отображал график в существующий объект осей. (Я не могу сказать, хотите ли вы сначала сгруппировать их по отраслям, а затем по городам на каждом участке или наоборот, но вы просто переключаете «промышленность» и «город» в двух groupby вызовах, если хотите наоборот вокруг.)

В этой версии пределы осей не выравниваются по подзаголовкам. Но общую идею можно отшлифовать, чтобы справиться с этим.

person BrenBarn    schedule 06.10.2014
comment
умное решение, которое работает с конкретной представленной проблемой, но не с основной проблемой карты. Однако, к сожалению, интерфейс графика geopandas не принимает те же самые аргументы ключевого слова, поэтому присваивание ax=ax оказывается некошерным. - person ako; 06.10.2014
comment
@ako: Я добавил к вашему вопросу тег geopandas. Если работа геопанд имеет решающее значение для вашего вопроса, вероятно, было бы хорошо сделать пример, который фокусируется на этом (то есть пример, который фактически использует геопанды). - person BrenBarn; 06.10.2014
comment
вы, наверное, правы; FWIW, поскольку было только несколько вопросов с меткой geopandas, я назвал его более общим вопросом о подключении к объектам подсекций, потому что я думал, что это увеличит вероятность ответа. - person ako; 06.10.2014