Maybe I am too used to R's wonderful ggplot-idiom when doing faceted charts (it takes numeric and string variables without protest) but the ideal way outside ggplot has certainly eluded me for some time getting to know the matplotlib world.
I am typically faceting a lot of bar charts by several dimensions, and have recently found the eminent seaborn library building on matplotlib which has an easy faceting interface.
Bar plots typically require a numeric vector (as opposed to a categorical string vector) for the x variable--here first some mock data and a basic plot:
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')
Which yields this plot. This dataframe method of plot can use indices to plot behind the scenes:

Now, onto seaborn which has a nice faceting interface. First I flatten the multiindices so I have columns instead (I think this is required for the 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 |
+----------+--------------+-------+------+
Calling this gives me the error 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)
However, I can hack it and turn one of the categorical variables back to a number:
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)
Which yields the approximate result (but with decimals on x).
So my question is--what is the best way to deal with categorical axes in the faceting example? (Incidentally noting that
f, (ax) = plt.subplots()
sns.barplot(df_city_grouped.industry, df_city_grouped.jobs, ax=ax, ci=None)
does work with categorical labels. outside the faceting idiom.)

sns.barploton theFacetGrid. There's no reason to withfactorplot, but you can pass any function toFacetGrid.mapit doesn't have to be in thepltnamespace.