【问题标题】:Horizontal grouped Barplot with Bokeh using dataframe使用数据框的散景水平分组条形图
【发布时间】:2020-09-13 13:48:18
【问题描述】:

我有一个数据框,我想按 Type 分组,然后按 Flag 分组并绘制一个图形以计算 ID 和另一个按 Type 分组的图形 FlagTotal 的总和散景中的列。 ')

 p.hbar(df,
   plot_width=800,
   plot_height=800,
   label='Type',
   values='ID',
   bar_width=0.4,
   group = ' Type', 'Flag'
   legend='top_right')
 [![Expected Graph ][2]][2]

如果 Bokeh 无法实现,我可以使用什么其他软件包来获得好看的图形(白色背景的鲜艳色彩)

【问题讨论】:

    标签: python-3.x bar-chart bokeh


    【解决方案1】:

    您可以通过使用散景作为后端的 holoviews 库来做到这一点。

    import pandas as pd
    import holoviews as hv
    from holoviews import opts
    hv.extension("bokeh")
    
    df = pd.DataFrame({
        "type": list("ABABCCAD"),
        "flag": list("YYNNNYNY"),
        "id": list("DEFGHIJK"),
        "total": [40, 100, 20, 60, 77, 300, 60, 50]
    })
    
    # Duplicate the dataframe
    df = pd.concat([df] * 2)
    print(df)
      type flag  id  total
    0    A    Y   1     40
    1    B    Y   2    100
    2    A    N   3     20
    3    B    N   4     60
    4    C    N   5     77
    5    C    Y   6    300
    6    A    N   7     60
    7    D    Y   8     50
    

    现在我们有了数据,让我们开始绘制它:

    def mainplot_hook(plot, element):
        plot.state.text(
            y="xoffsets", 
            x="total", 
            text="total", 
            source=plot.handles["source"],
            text_align="left",
            y_offset=9,
            x_offset=5
        )
        
    def sideplot_hook(plot, element):
        plot.state.text(
            y="xoffsets", 
            x="count", 
            text="count", 
            source=plot.handles["source"],
            text_align="left",
            y_offset=9,
            x_offset=5
        )
        
    # Create single bar plot for sum of the total column
    total_sum = df.groupby(["type", "flag"])["total"].sum().reset_index()
    total_sum_bars = hv.Bars(total_sum, kdims=["type", "flag"], vdims="total")
    
    # Create our multi-dimensional bar plot
    all_ids = sorted(df["id"].unique())
    counts = df.groupby(["type", "flag"])["id"].value_counts().rename("count").reset_index()
    id_counts_hmap = hv.Bars(counts, kdims=["type", "flag", "id"], vdims="count").groupby("type")
    
    
    main_plot = (total_sum_bars
                 .opts(hooks=[mainplot_hook], 
                       title="Total Sum", 
                       invert_axes=True)
    )
    
    side_plots = (
            id_counts_hmap
            .redim.values(id=all_ids, flag=["Y", "N"])
            .redim.range(count=(0, 3))
            .opts(
                opts.NdLayout(title="Counts of ID"), 
                opts.Bars(color="#1F77B4", height=250, width=250, invert_axes=True, hooks=[sideplot_hook]))
            .layout("type")
            .cols(2)
    )
    
    final_plot = main_plot + side_plots
    
    # Save combined output as html
    hv.save(final_plot, "my_plot.html")
    
    # Save just the main_plot as html
    hv.save(main_plot, "main_plot.html")
    

    如您所见,在全息视图中制作绘图的代码可能有点棘手,但它绝对是我推荐您使用的工具。尤其是如果您定期处理高维数据,一旦您掌握了语法,绘制它就变得轻而易举。

    【讨论】:

    • 谢谢。如何制作单杠? hbar 在这里工作吗
    • 要在全息视图中制作水平条,只需将invert_axes=True 传递给opts 的调用。要在左侧水平条上绘制图,请执行以下操作:total_sum_bars.opts(title="Total Sum", invert_axes=True) 然后要更改右侧的条,您需要将其传递给 opts.Bars(..., invert_axes=True)
    • 我应该将每个柱的总值添加到哪个函数。我想在图像上显示每个条的总值..
    • 我也看不到 spyder 控制台上的情节,有没有办法只将最终情节单独保存为图像或 pdf。?它在控制台中只显示:HoloMap [day] :Bars [flag,size] (count)
    • holoviews 还不能正确处理带有嵌套条形图的文本,因此您需要编写自己的钩子以将其添加到底层散景后端。查看更新的答案。你也可以通过在渲染的散景对象上调用 bokeh.io.show 来显示你的情节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 2016-10-29
    • 2020-06-29
    • 1970-01-01
    相关资源
    最近更新 更多