Reputation: 941
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
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