Search code examples
pythonpandasmatplotlibhistogram

Saving two different figures on different files with matplotlib


This may be obvious, but I can't do it. I'm new to Python and recently starting on matplotlib so I can't see the problem.

I am doing the following:

  • create a pandas.DataFrame
  • make a histogram and save as a png file
  • create a new column of the DataFrame
  • make a histogram of that columns and save as a new png file

What I get is two png files with the same figure: the DataFrame histogram. (I remember similar problems on MATLAB and it took time to me to find the way)

Here is the code:

import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Suppose 'housing' is a pandas.DataFrama with shape (20640, 11)

# Make a histogram of each column of housing data frame
housing.hist(bins=50, figsize=(20, 15))

# Save histogram as a file
os.makedirs('im', exist_ok=True)
plt.savefig('im/housing_hist.png')

# Create a new attribute which represent income category
housing["income_cat"] = pd.cut(housing["median_income"],
                               bins=[0., 1.5, 3.0, 4.5, 6., np.inf],
                               labels=[1, 2, 3, 4, 5])

# Create a histogram of income_cat
housing["income_cat"].hist()
plt.savefig('im/income_cat_hist.png')

I need help to save different files.

Thanks for your time.


Solution

  • It is more reliably to save the figure from the figure object. In Python (and MATLAB in more recent versions), figures are a particular data type. The pandas hist function returns an axes or array of axes.

    If you are making a single axes, you can get the figure using the figure property, and then call savefig from that.

    So something like this should work.

    ax1 = housing.hist(bins=50, figsize=(20, 15))
    ax1.figure.savefig('im/housing_hist.png')
    

    If you are making multiple axes, you would get a numpy array axes, which you can just flatten and get the first element of:

    axs1 = housing.hist(bins=50, figsize=(20, 15))
    axs1.ravel()[0].figure.savefig('im/housing_hist.png')
    

    Edit: To make it clear, for the second figure you should do:

    ax2 = housing["income_cat"].hist()
    ax2.figure.savefig('im/income_cat_hist.png')