Python Forum

Full Version: Dynamically placing axes in subplots via dataframe plot
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Using matplotlib with pandas, I'm trying to create a set of subplots in a figure.

As the number of plots to be included varies, the subplots layout must be calculated at runtime; then, two nested loops, the outer for the columns and the inner for the rows, are used to "fill" each subplot axis. All the data come from a unique dataframe, and are selected from different columns, together with their error bars.

I tried something like the following, but instead of getting a single figure with N subplots I get N figures, each with a single plot. I suppose this is due to the fact that I'm assigning the axes array contents to the result of dataframe.plot, rather than using the objects which get created by the subplots function. Yet, I cannot find a way of using them directly. I tried with the data argument of the axes plot function, but (apart from missing the commodities of the dataframe helpers, e.g. for error bars) it throws when assigned to a dataframe. I'm probably missing something obvious here, could anyone give a hint?

Here is a commented code excerpt:

# I want 3 cols and a variable number of rows,
# enough for all the dataframe columns (cols) to fit.
col_count = 3
row_count = math.ceil(len(cols) / col_count)

fig, axes = plt.subplots(row_count, col_count,
                         sharex='col', sharey='row')

# plot each dataframe column in a subplot
i = 0
for y in range(0, row_count):
    for x in range(0, col_count):
        if i >= len(cols):
            break
        # all the column names in the dataframe end with
        # _r for ratios, and _el/_eh for lo/hi error bars values,
        col = cols[i]
        colbase = col[:-1]
        el_col = colbase + "el"
        eh_col = colbase + "eh"
        # plot at y,x: how should I do here using dataframe helpers?
        axes[y, x] = df.plot.bar(x='key', y=col,
                                 yerr=[
                                     df[el_col] - df[col],
                                     df[eh_col] - df[col]
                                 ])
Not sure exactly because not tested, but I think you need to pass somewhat ax=... argument to the .bar method. Something like this:

df.plot.bar(x='key', y=col, yerr=[
                                     df[el_col] - df[col],
                                     df[eh_col] - df[col]
                                 ], ax = axes[y, x])
Another option is to use plt.sca to set current axes each time you need to plot the new graph.