使用数据框的带有散景的水平分组条形图

Horizontal grouped Barplot with Bokeh using dataframe

我有一个 Dataframe,我想按 Type 分组,然后 Flag 并绘制一个图表以计数 ID 和另一个按 Type 分组的图表, Flag 和 Bokeh 中 Total 列的总和。 ')

 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 无法实现,我可以使用什么其他包来获得漂亮的图形(白色背景的鲜艳颜色)

您可以使用 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")

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