如何在matplotlib中自定义水平条形图?

2024-06-01 05:25:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在努力将matplotlib图嵌入到tkintergui中;我本可以使用QTPython,它看起来非常整洁,但为时已晚。你知道吗

这是我下面的代码,用于更新TkinterGUI中的图形(它是嵌入式的,没有外部窗口),我想调整图表的大小以正确地适应。到目前为止,我尝试了以下方法:

1)紧凑布局:图_findin.U布局() 2) Yticks包装正确 3) 我试过从0.1到0.6的不同宽度

我的主要问题是降低灰色背景框(网格线框或子图)的高度。这将使标题完全可见,并且看起来与其他图形一致。我也希望yèU轴标签被包装,但仍然在现有的框架可见。你知道吗

这是我的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)

我的图表是这样的:

enter image description here


Tags: nameinrectmodforgetifcount
1条回答
网友
1楼 · 发布于 2024-06-01 05:25:43

我想出了一个舒适的适合,但仍然不能使yticks显得整洁。你知道吗

锁销是减少酒吧宽度和隐藏所有其他y轴配件。添加Wrap=True和垂直对齐标签使其看起来很漂亮。你知道吗

    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')

现在是这样的:

enter image description here

相关问题 更多 >