Python使用bokeh制作条形图分类对比

报错:

AttributeError: unexpected attribute 'legend_field' to VBar, possible attributes are bottom, fill_alpha...

bokeh在低版本中1.34中使用legend和高版本是不一样的,在2.4.X中可以用legend_field='label'

,但是在低版本中需要使用legend='label'

源代码:

import csv
from bokeh.palettes import d3
from bokeh.layouts import column
from bokeh.models import ColumnDataSource,FactorRange
from bokeh.plotting import figure, output_file, show
from bokeh.transform import factor_cmap


def plot_recall_precison(csv_path,html_path):
    # 读取csv至字典
    csvFile = open(csv_path, "r")
    reader = csv.reader(csvFile)

    # 建立空列表
    result = {}
    recall_title='Recall Rate:'


    precision_title='Precision Rate:'

    #csv文件的行数
    lines = len(open(csv_path).readlines())
    for item in reader:
        # 忽略第一行,reader对象其实就是由CSV文档的多行数据构成的,每行数据会有一个属性:line_num表示行
        if reader.line_num == 1:
            # print(item[len(item)-1])
            recall_title =recall_title+str(round(float(item[len(item)-1])*100,4))+'%'
            continue
        #忽略最后统计数量的两行
        if reader.line_num < lines-1:
            result[item[0]]=item[1:len(item)-1]
        #倒数第二行是召回率
        if reader.line_num == lines-1:
            precision_title = precision_title+str(round(float(item[0])*100,4))+'%'

    csvFile.close()

    #把字典的key转换为列表
    keys = list(result.keys())


    #复制列表的函数[1,2,3]->[1,1,2,2,3,3]
    def double_list(list1):
        l2 =[]
        for i in list1:
            l2.append(i)
            l2.append(i)
        return l2

    #类别名称
    categorys = ['total','recall']
    categorys_pre = ['total','precision']

    #codes的数量和召回数量
    total_count = []
    recall_count = []

    #codes名称
    codes = []
    #legend图例的分组
    labels = []
    #转换字符为数字类型, '0123': ['54.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '0.0', '1.0']
    # 变为'0123': [54.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]

    # 建立精准率的空列表
    precision_totalcount = [0]*len(result)

    i = 0
    for item in result.items():
        result[item[0]] = [float(x) for x in result[item[0]]]
        total_count.append(sum(result[item[0]]))
        codes.append(item[0])
        labels.append(item[0])
        labels.append(item[0])
        precision_totalcount = list(map(lambda a,b:a+b,precision_totalcount,result[item[0]]))
        recall_count.append(float(item[1][i]))
        # print(item[0],item[1],item[1][i])
        i = i +1

    print('*'*10)
    # print(result)
    print(result.keys())

    # print('total_count',total_count)
    # print('codes',codes*2)
    # print('recall_count',recall_count)
    # print('precision_totalcount',precision_totalcount)
    # print('labels',labels)


    hover_totalcount = double_list(total_count)
    hover_recallcount = double_list(recall_count)
    hover_recallrate = list(map(lambda a,b : round(a/b,4) if b !=0 else 0,hover_recallcount,hover_totalcount))
    hover_precision_tatalcount = double_list(precision_totalcount)
    hover_precision_rate = list(map(lambda a,b : round(a/b,4) if b !=0 else 0,hover_recallcount,hover_precision_tatalcount))
    print(hover_recallrate)
    print(hover_precision_rate)

    data = {'codes':codes,
            'total':total_count,
            'recall':recall_count,
            'pre_total':precision_totalcount}

    # create [('0123', 'total'), ('0123', 'recall'), ('1101', 'total'), ('1101', 'recall')
    x = [ (code, category) for code in codes for category in categorys ]
    x_pre = [ (code, category) for code in codes for category in categorys_pre]


    counts = sum(zip(data['total'], data['recall']), ()) # like an hstack
    counts_pre = sum(zip(data['pre_total'], data['recall']), ()) # like an hstack


    source = ColumnDataSource(data=dict(x=x, counts=counts,label=labels,
                                        hover_recallcount=hover_recallcount,hover_totalcount=hover_totalcount,hover_recallrate=hover_recallrate))

    source_pre = ColumnDataSource(data=dict(x_pre=x_pre, counts_pre=counts_pre,label=labels,
                                        hover_recallcount=hover_recallcount,hover_precision_tatalcount=hover_precision_tatalcount,hover_precision_rate=hover_precision_rate))

    TOOLTIPS = [
        ("Total", "@hover_totalcount"),
        ("Recall", "@hover_recallcount"),
        ('Recall Rate',"@hover_recallrate")
    ]

    TOOLTIPS_PRE = [
        ("Total", "@hover_precision_tatalcount"),
        ("Recall", "@hover_recallcount"),
        ('Precision Rate', "@hover_precision_rate")
    ]

    output_file(html_path)
    color_palette = d3['Category20'][20]+d3['Category20c'][20]

    #toolbar_location=None为不显示自带的那些功能,tools=""表示柱状图是不可以拖动改变的
    p = figure(x_range = FactorRange(*x),height=300,width=1000,tooltips=TOOLTIPS,
               title=recall_title,toolbar_location=None,tools="")
    #使用color映射条形颜色,其中调色板用d3 https://docs.bokeh.org/en/latest/docs/reference/palettes.html?highlight=viridis
    p.vbar(x='x', top='counts', width=0.9, bottom=0, color= factor_cmap('x', palette=color_palette[0:len(counts)],
          factors=x),legend='label',source=source)

    #toolbar_location=None为不显示自带的那些功能,tools=""表示柱状图是不可以拖动改变的
    p_pre= figure(x_range = FactorRange(*x_pre),height=300,width=1000,tooltips=TOOLTIPS_PRE,
               title=precision_title,toolbar_location=None,tools="")
    p_pre.vbar(x='x_pre', top='counts_pre', width=0.9, bottom=0, color= factor_cmap('x_pre', palette=color_palette[0:len(counts_pre)],
          factors=x_pre),legend='label',source=source_pre)


    #y的起始坐标是从0开始
    p.y_range.start = 0
    p.y_range.end = max(total_count)+100
    #x的起始柱状图距离原点的距离
    p.x_range.range_padding = 0.1
    p.xaxis.major_label_orientation = 0.5

    #网格线设置为无
    p.xgrid.grid_line_color = None
    #legend图例水平且居中
    p.legend.orientation = "horizontal"
    p.legend.location = "top_center"
    # 去除网格线
    p.grid.visible = False

    ##精准率的
    #y的起始坐标是从0开始
    p_pre.y_range.start = 0
    p_pre.y_range.end = max(total_count)+100
    #x的起始柱状图距离原点的距离
    p_pre.x_range.range_padding = 0.1
    p_pre.xaxis.major_label_orientation = 0.5

    #网格线设置为无
    p_pre.xgrid.grid_line_color = None
    #legend图例水平且居中
    p_pre.legend.orientation = "horizontal"
    p_pre.legend.location = "top_center"
    # 去除网格线
    p_pre.grid.visible = False

    show(column(p,p_pre))

if __name__ == '__main__':
    csv_path = r"H:\B1project\Fastercnn_result\confusion_matrix调阈值\test.csv"
    html_path = r'H:\recall_pre.html'
    plot_recall_precison(csv_path,html_path)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大宇进阶之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值