簡體   English   中英

如何在matplotlib中自定義擬合水平條形圖?

[英]How to custom fit horizontal bar plot in matplotlib?

我一直在努力將我的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)

這是我的圖形的外觀:

在此處輸入圖片說明

我想出了一個合適的方法,但仍然無法使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')

現在是這樣的:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM