我正在尝试制作6个饼图,每个饼图都嵌入了图像。我已经能够生成饼图和子图(空)。但是,我不了解在右下角生成所有图表的行为。 (它目前正在做)。另外,当我运行6个图表时,我收到内存错误。 (当我运行两个图表时不会发生这种情况)
Tkinter回调中的异常:
的MemoryError
我包含了我的代码,有足够的数据线来生成两个图表。可以使用绘图和保存实体块png文件轻松构建5个丢失的png文件。
我也意识到这里有两个问题,但由于它们都来自相同的代码,我正在询问这两个问题。
所以 1)如何让子图将饼图分布在自己的位置。 In Matplotlib, what does the argument mean in fig.add_subplot(111)?似乎也没有帮助我。
2)我怎样才能避免记忆错误(我可能已经开了一些东西而且不知道如何关闭它,但我不知道这个Tkinter and pyplot running out of memory出现了什么或怎么样有类似的问题,但我无法理解它是如何修复的
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import sys
import scipy.stats
#import panda as pd
import numpy as np
size_distribution = np.array([
[ 1 , 1 , 0.48 , 0.42 , 0.10 ],
[ 1 , 1 , 0.52 , 0.38 , 0.10 ],
[ 2 , 2 , 0.38 , 0.42 , 0.20 ],
[ 2 , 2 , 0.42 , 0.38 , 0.20 ]])
def name_of_files(): # files named as such in directory with python script
Variety = np.array(['_A_', '_B_']) #Variety of tested stuff
Treatment = np.array(['_1_', '_2_', '_3_']) # Treatment of stuff
Cut = np.array(['_i_', '_ii_']) # Cut of stuff
return Variety, Treatment, Cut
def label(): # provides info on labelling in pie chart
var = np.array(['A_', 'B_'])
treat = np.array(['1_', '2_', '3_'])
return var, treat
def size(xx, strt, end): #produces individual pie chart with plt.show() or sends wedges to main
Variety, Treatment, Cut = name_of_files()
var, treat = label()
long = int(len(size_distribution))
count = int(strt)
cut = int(0)
while count < (long - 1) and count < end:
coarse = np.mean([xx[count][2], xx[count+1][2]])
fine = np.mean([xx[count][3], xx[count+1][3]])
residue = np.mean([xx[count][4], xx[count+1][4]])
name = (str(Variety[int(xx[count][0])-1]) +
str(Treatment[int(xx[count][1])-1]) +
str(Cut[int(cut)]) +
'.png')
#print(name, cut)
if cut == 0:
name_coarse = name
label_coarse = (str(var[int(xx[count][0])-1]) + '\n' +
str(treat[int(xx[count][1])-1]) + '\n' +
'coarse fraction:\n' + str(np.around(coarse, 3)*100) + '%')
#print(label_coarse, coarse)
cut = int(1)
elif cut == 1:
name_fine = name
label_fine = (str(var[int(xx[count][0])-1]) + '\n' +
str(treat[int(xx[count][1])-1]) + '\n' +
'fine fraction:\n' + str(np.around(fine, 3)*100) + '%')
label_residue = ('\n\n' + str(var[int(xx[count][0])-1]) + ', ' +
str(treat[int(xx[count][1])-1]) + '\n' +
'residue fraction: ' + str(np.around(residue, 3)*100) + '%')
#print(label_fine, fine)
#print(label_residue, residue)
#print('\t\t\t\t', fine+coarse+residue)
cut = int(0)
#print('\n\n\t\t\tcount = ', count)
count += 2
#print('\n\n\t\t\tcount = ', count)
file_index = np.array([name_coarse, 'Black.png', name_fine])
labels = np.array([label_coarse, label_residue, label_fine])
total = [coarse, residue, fine]
plt.gca().axis('equal')
wedges, texts = plt.pie(total, startangle=90, labels=labels,
wedgeprops = { 'linewidth': 3, "edgecolor" :"k",
"fill":False, })
positions = [(-1,0.3),(0,-0.5),(0.5,0.5)]
zooms = [0.4,0.4,0.4]
for i in range(3):
#print('\ti = ', i)
fn = str(file_index[i]).format(labels[i].lower(), fontsize=20)
img_to_pie(fn, wedges[i], xy=positions[i], zoom=zooms[i] )
wedges[i].set_zorder(10)
#plt.show() #shows the pie chart nicely
#plt.close('all')
#print('Wedges type: ',type(wedges),'\nLength: ', len(wedges))
#print('Texts type: ',type(wedges),'\nTexts: ', len(wedges))
#print(type(texts), len(texts))
#print(locals())
return wedges
def img_to_pie( fn, wedge, xy, zoom=1, ax = None):
if ax==None: ax=plt.gca()
im = plt.imread(fn, format='png')
path = wedge.get_path()
patch = PathPatch(path, facecolor='none')
plt.gca().add_patch(patch)
imagebox = OffsetImage(im, zoom=zoom, clip_path=patch, zorder=-10)
ab = AnnotationBbox(imagebox, xy, xycoords='data', pad=0, frameon=False)
ax.add_artist(ab)
return ()
def main():
fig = plt.figure()
ho = fig.add_subplot(1, 2, 1)
hm = fig.add_subplot(1, 2, 2)
'''
f, ((ho , hm, hs), (mo, mm, ms)) = (
plt.subplots(nrows=2, ncols=3, sharex=True, sharey=True,
squeeze=False, subplot_kw=None, gridspec_kw=None))
#plt.show() # six empty plots as expected'''
j = [ho, hm]#, hs]#, mo, mm, ms]
x = [0, 2]#, 4]#, 6, 8, 10]
count = 0
int(count)
while count < len(x):
j[count] = size(size_distribution, x[count], x[count]+2)
print(x[count], '\n', j[count])
count += 1
print(ho, '\n', hm)
plt.show()
main()
答案 0 :(得分:1)
首先,我在回答this question时为你写的函数接受了一个参数ax
,你应该用它来设置你想要绘制的轴。
此外,您需要将饼图绘制到要显示它的轴ax
,即使用ax.pie(..)
而不是plt.pie(..)
。
您可以使用
创建子图f, ax_arr = plt.subplots(nrows=2, ncols=3)
见other recent question的答案,并将ax_arr
内的轴提供给size
函数,然后您需要像size(xx, strt, end, ax)
一样编写。
以下代码
import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import scipy.stats
import numpy as np
size_distribution = np.array([
[ 1 , 1 , 0.48 , 0.42 , 0.10 ],
[ 1 , 1 , 0.52 , 0.38 , 0.10 ],
[ 2 , 2 , 0.38 , 0.42 , 0.20 ],
[ 2 , 2 , 0.42 , 0.38 , 0.20 ]])
def name_of_files(): # files named as such in directory with python script
Variety = np.array(['_A_', '_B_']) #Variety of tested stuff
Treatment = np.array(['_1_', '_2_', '_3_']) # Treatment of stuff
Cut = np.array(['_i_', '_ii_']) # Cut of stuff
return Variety, Treatment, Cut
def label(): # provides info on labelling in pie chart
var = np.array(['A_', 'B_'])
treat = np.array(['1_', '2_', '3_'])
return var, treat
filenames=["data/blueberries.png", "data/blackberries.png","data/raspberries.png"]
def size(xx, strt, end, ax=None): #produces individual pie chart with plt.show() or sends wedges to main
if not ax: ax=plt.gca()
Variety, Treatment, Cut = name_of_files()
var, treat = label()
long = int(len(size_distribution))
count = int(strt)
cut = int(0)
while count < (long - 1) and count < end:
coarse = np.mean([xx[count][2], xx[count+1][2]])
fine = np.mean([xx[count][3], xx[count+1][3]])
residue = np.mean([xx[count][4], xx[count+1][4]])
name = (str(Variety[int(xx[count][0])-1]) +
str(Treatment[int(xx[count][1])-1]) +
str(Cut[int(cut)]) +
'.png')
if cut == 0:
name_coarse = name
label_coarse = (str(var[int(xx[count][0])-1]) + '\n' +
str(treat[int(xx[count][1])-1]) + '\n' +
'coarse fraction:\n' + str(np.around(coarse, 3)*100) + '%')
cut = int(1)
elif cut == 1:
name_fine = name
label_fine = (str(var[int(xx[count][0])-1]) + '\n' +
str(treat[int(xx[count][1])-1]) + '\n' +
'fine fraction:\n' + str(np.around(fine, 3)*100) + '%')
label_residue = ('\n\n' + str(var[int(xx[count][0])-1]) + ', ' +
str(treat[int(xx[count][1])-1]) + '\n' +
'residue fraction: ' + str(np.around(residue, 3)*100) + '%')
cut = int(0)
count += 2
file_index = np.array([name_coarse, 'Black.png', name_fine])
labels = np.array([label_coarse, label_residue, label_fine])
total = [coarse, residue, fine]
ax.axis('equal')
wedges, texts = ax.pie(total, startangle=90, labels=labels,
wedgeprops = { 'linewidth': 3, "edgecolor" :"k",
"fill":False, })
positions = [(-1,0.3),(0,-0.5),(0.5,0.5)]
zooms = [0.4,0.4,0.4]
for i in range(3):
#fn = str(file_index[i]).format(labels[i].lower(), fontsize=20)
fn = filenames[i]
img_to_pie(fn, wedges[i], xy=positions[i], zoom=zooms[i],ax=ax )
wedges[i].set_zorder(10)
return wedges
def img_to_pie( fn, wedge, xy, zoom=1, ax = None):
if ax==None: ax=plt.gca()
im = plt.imread(fn, format='png')
path = wedge.get_path()
patch = PathPatch(path, facecolor='none')
ax.add_patch(patch)
imagebox = OffsetImage(im, zoom=zoom, clip_path=patch, zorder=10)
ab = AnnotationBbox(imagebox, xy, xycoords='data', pad=0, frameon=False)
ax.add_artist(ab)
return ()
def main():
f, ax_arr = plt.subplots(nrows=2, ncols=3)
x = [0, 2, 4, 6, 8, 10]
count = 0
for i, ax in zip(x, ax_arr.flatten()):
wedges = size(size_distribution, x[count], x[count]+2, ax=ax)
plt.show()
main()
然后产生这个情节
我不关心看标签,因为这部分代码很乱(下次请问请创建一个没有多余标签的最小例子)。
你得到的错误可能来自我注释掉的那一行,这没有用:
#fn = str(file_index[i]).format(labels[i].lower(), fontsize=20)
因为str
没有fontsize
参数。