Возможно, я слишком привык к R's
замечательным ggplot
-idiom, когда вы делаете граненые диаграммы (он принимает числовые и строковые переменные без протеста), но идеальный способ вне ggplot, безусловно, ускользнул от меня для некоторых время, чтобы узнать мир matplotlib.Matplotlib/Seaborn barplot - строки по оси x
Я, как правило, украшаю множество гистограмм по нескольким размерам, и недавно нашел знаменитое здание библиотеки на морском дне на matplotlib, которое имеет легкий фасетный интерфейс.
Бар участки, как правило, требуют числового вектора (в отличие от категорического вектора строк) для переменного х - вот первых нескольких фиктивных данных и основной сюжета:
import pandas as pd
import numpy as np
import seaborn as sns
N = 100
## generate toy data
ind = np.random.choice(['retail','construction','information'], N)
cty = np.random.choice(['cooltown','mountain pines'], N)
age = np.random.choice(['young','old'], N)
jobs = np.random.randint(low=1,high=250,size=N)
## prep data frame
df_city = pd.DataFrame({'industry':ind,'city':cty,'jobs':jobs,'age':age})
df_city_grouped = df_city.groupby(['city','industry','age']).sum()
df_city_grouped.unstack().plot(kind='bar',stacked=True,figsize=(9, 6),title='Jobs by city, industry, age group')
Что дает этот участок. Этот метод dataframe участка может использовать индексы для построения за кадром:
Теперь на Сиборн, который имеет приятный интерфейс огранки. Сначала я сплющиваю мультииндексы, поэтому вместо столбцов я использую столбцы (я думаю, это требуется для API).
df_city_grouped.reset_index(inplace=True)
df_city_grouped.head()
+----------+--------------+-------+------+
| city | industry | age | jobs |
+----------+--------------+-------+------+
| cooltown | construction | old | 563 |
+----------+--------------+-------+------+
| cooltown | construction | young | 1337 |
+----------+--------------+-------+------+
| cooltown | information | old | 1234 |
+----------+--------------+-------+------+
| cooltown | information | young | 1402 |
+----------+--------------+-------+------+
| cooltown | retail | old | 1035 |
+----------+--------------+-------+------+
Призыв к этому дает мне ошибку TypeError: cannot concatenate 'str' and 'float' objects
.
g = sns.FacetGrid(df_city_grouped, col="industry", row="city", margin_titles=True)
g.map(plt.bar, "age","jobs", color="darkred", lw=0)
Однако, я могу взломать его и превратить один из категориальных переменных обратно в номер:
mapping = {
'young': 1,
'middle':2,
'old':3}
df_city_grouped['age2']=df_city_grouped.age.map(mapping)
g = sns.FacetGrid(df_city_grouped, col="industry", row="city", margin_titles=True)
g.map(plt.bar, "age2","jobs", color="darkred", lw=0)
что дает приблизительный результат (но с десятичными знаками на х). Итак, мой вопрос - это лучший способ справиться с категориальными осями в примере огранки? (Кстати отметить, что
f, (ax) = plt.subplots()
sns.barplot(df_city_grouped.industry, df_city_grouped.jobs, ax=ax, ci=None)
делает работу с категорическими этикетками. Вне фасетизации идиомы.)
Кстати, вы могли бы также отображенной 'sns.barplot' на' FacetGrid'. Нет причин для 'factorplot', но вы можете передать любую функцию в' FacetGrid.map', она не должна находиться в пространстве имен 'plt'. – mwaskom
классный материал. API довольно аккуратный. – ako