问题描述
我有一个数据框,我想按Type
分组,然后Flag
并绘制一个ID
计数的图形和另一个按Type
分组的图形,{ {1}}和bokeh中Flag
列的总和。
')
Total
如果无法使用bokeh,我可以使用其他哪个包来获得美观的图形(白色背景的鲜艳颜色)
解决方法
您可以使用holoviews库执行此操作,该库使用bokeh作为后端。
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,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,x="count",text="count",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,"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")
如您所见,在holoviews中进行绘图的代码可能会有些棘手,但绝对是我推荐您使用的工具。尤其是如果您定期处理高维数据,则一旦掌握语法,就可以轻松绘制。