我一直在努力将我的matplotlib图形嵌入到tkinter GUI中。我本可以使用QTPython,它看上去确实很整洁,但是为时已晚。
这是我下面的代码,用于更新tkinter GUI中的图形(它是嵌入式的,没有外部窗口),我想调整图表的大小以正确放置。到目前为止,我已经尝试了以下方法:
1)紧密布局:fig_findin.tight_layout() 2)Yticks包装真实 3)我尝试过从0.1到0.6的不同条形宽度
我的主要问题是减小灰色背景框(网格线框或子图)的高度。这样可以使标题完全可见,并且看起来与其他图形一致。我还希望包裹y_axis标签,但在现有框架中仍然可见。
这是我的matplotlib图代码。
def animate_artifact_graph(i):
#######################################
''' GRAPH START '''
#######################################
## DATA
x_cat = [x[1] for x in db.query_artifact()]
x_cat = x_cat[:-2]
y_count = {}
for i in x_cat:
y_count[i] = 0
artifact_name,proj_name,mod_name = artifact_type_select.get() ,proj_select.get(),proj_mod_select.get()
if(artifact_name == 'All'):
artifact_name = db.query_artifact_name()
else:
artifact_name = [artifact_name]
observations_fr_project = db.query_closed_findings_by_project(proj_name,mod_name,artifact_name)
title = proj_name + " - " + mod_name
for i in observations_fr_project:
y_count[i[2]] = y_count[i[2]] + 1
y_count = { k:v for k, v in y_count.items() if v > 0 and k != 'RTM'}
x = list(y_count.keys())
y = list(y_count.values())
# ## SHOW
# rects = ax.patches
# labels = [ i for i in list(y_count.values())]
# for rect, label in zip(rects, labels):
# if(rect.get_height() > 0):
# height = rect.get_height() - 1.50
# width = rect.get_width() /2
# ax.text(rect.get_x() + width, rect.get_y()+height-0.26,label)
# ax.set_ylabel("Observations", fontsize=12)
# ax.set_xlabel("Artifact Type", fontsize=12)
ax.clear()
now = datetime.datetime.now()
date_display = now.strftime('%A, %d %B %Y, %H:%M')
ax.set_title (title + "\n" + "Total number of findings per deliverable type\n(as of " + date_display + ")", fontsize=8)
def func(pct, allvals):
absolute = int(pct/100.*np.sum(allvals))
return "{:.1f}%\n{:d}".format(pct, absolute)
wedges, texts, autotexts = ax.pie(y, autopct=lambda pct: func(pct, y),
textprops=dict(color="w"))
ax.legend(wedges, x,
title="Artifact Types",
loc="center left",
bbox_to_anchor=(1, 0, 0.5, 1))
fig_artif.tight_layout()
ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
#######################################
''' GRAPH END '''
#######################################
def animate_finding_graph(i):
#######################################
''' GRAPH START '''
#######################################
## DATA
x_cat = [x[1] for x in db.query_finding()]
y_count = {}
for i in x_cat:
y_count[i] = 0
artifact_name,proj_name,mod_name = artifact_type_select.get() ,proj_select.get(),proj_mod_select.get()
if(artifact_name == 'All'):
artifact_name = db.query_artifact_name()
else:
artifact_name = [artifact_name]
observations_fr_project = db.query_closed_findings_by_project(proj_name,mod_name,artifact_name)
title = proj_name + " - " + mod_name
for i in observations_fr_project:
y_count[i[1]] = y_count[i[1]] + 1
y_count = { k:v for k, v in y_count.items() if v > 0 and k != 'nan'}
y_count = OrderedDict(sorted(y_count.items(), key=lambda kv: kv[1],reverse=True))
if(len(list(y_count.keys())) >= 5):
to_remove = list(y_count.keys())[5:]
for x in to_remove:
del y_count[x]
x = list(y_count.values())
y = list(y_count.keys())
## SHOW
ay.clear()
bar_width = 0.4
ay.barh(y,x,bar_width,align='edge',color='yellow')
ay.invert_yaxis()
rects = ay.patches
# print("rects",len(rects))
labels = [ i for i in list(y_count.values())]
# print("\n")
for rect, label in zip(rects, labels):
height = rect.get_height()/2
width = rect.get_width() - 0.50
ay.text(rect.get_x() + width, rect.get_y()+height,label,fontsize=8)
ay.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labelbottom=False) # labels along the bottom edge are off
ay.set_yticklabels(y,fontsize=6,wrap=True)
for tick in ay.yaxis.get_major_ticks():
tick.label1.set_verticalalignment('center')
now = datetime.datetime.now()
date_display = now.strftime('%A, %d %B %Y, %H:%M')
ay.set_title (title + "\n" + "Top 5 Deliverables.", fontsize=6)
#######################################
## ''' GRAPH END '''
#######################################
def artifact_graph():
canvas_artifact = FigureCanvasTkAgg(fig_artif, master=tab1_closed_observations)
canvas_artifact.get_tk_widget().grid(row=7,column=0,padx=10,pady=5,columnspan=3)
ani = animation.FuncAnimation(fig_artif, animate_artifact_graph,interval=500)
canvas_artifact.draw()
def export_win():
output_folder = "./Reports/" + proj_select.get() + " -- " + proj_mod_select.get()
if not os.path.exists(output_folder):
os.makedirs(output_folder)
fig_artif.savefig(output_folder + "/artifact.png")
export_artifact_graph = Button(tab1_closed_observations, text='Export', command=export_win)
export_artifact_graph.grid(row=6,column=0,padx=70,pady=20,sticky='we',columnspan=2)
def finding_category():
canvas_finding = FigureCanvasTkAgg(fig_findin, master=tab1_closed_observations)
canvas_finding.get_tk_widget().grid(row=7,column=5,padx=10,pady=5,columnspan=3)
ani = animation.FuncAnimation(fig_findin, animate_finding_graph,interval=500)
canvas_finding.draw()
def export_win():
output_folder = "./Reports/"+ proj_select.get() + " -- " + proj_mod_select.get()
if not os.path.exists(output_folder):
os.makedirs(output_folder)
fig_findin.savefig(output_folder + "/finding.png")
export_finding_graph = Button(tab1_closed_observations, text='Export', command=export_win)
export_finding_graph.grid(row=6,column=5,padx=70,pady=20,sticky='we',columnspan=3)
这是我的图表的外观:
答案 0 :(得分:0)
我想出了如何贴身的方法,但仍然无法使yticks显得整洁。
要抓住的是减小杆的宽度并隐藏所有其他y轴附件。添加Wrap =垂直和垂直对齐标签会使它看起来很漂亮。
bar_width = 0.4
ay.barh(y,x,bar_width,color='yellow')
ay.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labelbottom=False
)
ay.set_yticklabels(y,fontsize=6,wrap=True)
for tick in ay.yaxis.get_major_ticks():
tick.label1.set_verticalalignment('center')
这是现在的样子: