15

I am using the following code, trying to plot the histogram of every column of a my pandas data frame df_in as subplot of a big figure.

%matplotlib notebook
from itertools import combinations
import matplotlib.pyplot as plt

fig, axes = plt.subplots(len(df_in.columns) // 3, 3, figsize=(12, 48))
for x in df_in.columns:
    df_in.hist(column = x, bins = 100)

fig.tight_layout()

However, the histogram didn't show in the subplot. Any one knows what I missed? Thanks!

amance
  • 883
  • 4
  • 14
Edamame
  • 23,718
  • 73
  • 186
  • 320

4 Answers4

14

I can't comment burhan's answer because I don't have enough reputation points. The problem with his answer is that axes isn't one-dimensional, it contains axes triads, so it needs to be unrolled:

%matplotlib notebook
from itertools import combinations
import matplotlib.pyplot as plt

fig, axes = plt.subplots(len(df_in.columns)//3, 3, figsize=(12, 48))

i = 0
for triaxis in axes:
    for axis in triaxis:
        df_in.hist(column = df_in.columns[i], bins = 100, ax=axis)
        i = i+1
Pascal Antoniou
  • 181
  • 1
  • 5
7
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

fig, axis = plt.subplots(2,3,figsize=(8, 8))
df_in.hist(ax=axis)

The above will plot a 2*3 (total 6 histogram for your dataframe). Adjust the rows and columns as per your arrangement requirements(# of columns)

My TA @Benjamin once told me , dataframe means do not have to use for loop.

T D
  • 1,080
  • 2
  • 13
  • 20
3

You need to specify which axis you are plotting to. This should work:

fig, axes = plt.subplots(len(df_in.columns)//3, 3, figsize=(12, 48))
for col, axis in zip(df_in.columns, axes):
    df_in.hist(column = col, bins = 100, ax=axis)
burhan
  • 924
  • 4
  • 11
  • I got this error: ValueError: The number of passed axes must be 1, the same as the output plot. How do I fix the axes here? Thanks – Edamame Sep 22 '16 at 18:51
  • I didn't pay attention to the line that generate the axes. There may be a problem there, change it depending on how you want to present the plot. This will show all of them side by side for example. "fig, axes = plt.subplots(1, len(df_in.columns))". Let me know if this works. – burhan Sep 22 '16 at 19:13
  • 4
    I like this answer more than Pascal's below, but as he mentions there is an error. For me axes.flatten() did the trick – Marcus V. Nov 07 '17 at 21:34
0

Stumbled on this ancient post and figured I'd add a correct answer, the above answers are mostly right but ignore the fact that they need to +1 the flooring function. Somewhat addressed in @burhan 's answer but just cleaned up a bit here:

import seaborn as sns
from matplotlib import pyplot as plt

def plot_univariate_distributions(df, numcols=3, fig_kwargs = dict()):
    fig, axes = plt.subplots(1+len(df.columns)//numcols, numcols, **fig_kwargs)
    for col, ax in zip(df.columns, axes.flat):
        sns.histplot(df[col], ax=ax)
        ax.set_title(col, size=10)
    plt.tight_layout()

plot_univariate_distributions(mydf, fig_kwargs={'figsize':[10,5]})
Ben Saunders
  • 929
  • 10
  • 20