3pitt
3pitt

Reputation: 941

Save Pyplot 'Hist' to File

I'm writing several different plots to disk with pyplot. Most of these are scatter plots; hist is specifically resisting the approach that works elsewhere.

ind_list=range(175,185)
plt_fail_rate1=plt.scatter(ind_list,perf_fail_rate1)
plt.title('Proportion of Failed (size>1 and all unique) Clusters')
plt_fail_rate1.figure.savefig(paath+'/fail_rate1.png')
plt.clf()

This approach works for all scatterplots. Below is the analog for histograms which does not work. Note that the problem is with savefig specifically - if I replace that line with plt.show(), a normal histogram appears in the GUI

distr_tmp=tf.opc_size_distr() # get a list from a class
plt_opc_size=plt.hist(distr_tmp)
plt.title('Number of Codes Per Cluster')
#plt.show()
#plt_opc_size.savefig(paath+'/size_distr.png')
#plt_opc_size.figure.savefig(paath+'/size_distr.png')
plt.clf()

If I use .figure.savefig(), I get tuple object has no attribute figure.

If I use .savefig(), I get tuple object has no attribute savefig. Also, in response to a comment, I tried .figure().savefig() and that doesn't work either.

I've used a python shell session to figure to verify the hist-specific problem. Namely, if you store plt.scatter() in some variable, you can then call .figure.savefig() on that variable with no problem. So, the problem can so summarized as follows:

ind_list=[1,2,3]
data_list=[10,-5,-15]
x=plt.scatter(ind_list,data_list)
x.figure.savefig('test.png') # works fine on my laptop
hist_list=[1925,1970]
x=plt.hist(hist_list)
#plt.show() # shows a valid if sparse histogram in a new window
x.figure.savefig('test2.png') #all permutations fail

Note that if you're testing this from a shell, you need to be careful (call plt.clf() I believe) after you call show(), otherwise even the proper call will fail due to can't invoke 'wm' command error.

Upvotes: 1

Views: 2733

Answers (1)

Diziet Asahi
Diziet Asahi

Reputation: 40707

The problem is that plt.hist() returns a tuple containing 3 elements:

n : array or list of arrays

The values of the histogram bins. See normed or density and weights for a description of the possible semantics. If input x is an array, then this is an array of length nbins. If input is a sequence arrays [data1, data2,..], then this is a list of arrays with the values of the histograms for each of the arrays in the same order.

bins : array

The edges of the bins. Length nbins + 1 (nbins left edges and right edge of last bin). Always a single array even when multiple data sets are passed in.

patches : list or list of lists

Silent list of individual patches used to create the histogram or list of such list if multiple input datasets.

Only the last one (patches) is a list of Artist objects which contain a reference to your figure.

For your code to work, you'd therefore have to do something like:

plt_opc_size[2][0].figure.savefig(paath+'/size_distr.png')

The [2] accesses the 3rd element of the tuple (the list of patches) and [0] the first Artist in that list.

However, this is not the most elegant way to write your code. You can obtain a reference to your Figure using plt.gcf(). The following would therefore work in all cases:

distr_tmp=tf.opc_size_distr() # get a list from a class
plt_opc_size=plt.hist(distr_tmp)
plt.title('Number of Codes Per Cluster')
plt.gcf().savefig(paath+'/size_distr.png')
plt.clf()

Upvotes: 3

Related Questions