【问题标题】:Change the order of bars in a grouped barplot with hvplot/holoviews使用 hvplot/holoviews 更改分组条形图中的条形顺序
【发布时间】:2020-01-16 22:15:44
【问题描述】:

我尝试创建分组条形图,但不知道如何影响条形图的顺序。

鉴于这些示例数据:

import pandas as pd
import hvplot.pandas

df = pd.DataFrame({
    "lu": [200, 100, 10], 
    "le": [220, 80, 130], 
    "la": [60, 20, 15], 
    "group": [1, 2, 2],
})
df = df.groupby("group").sum()

我想创建一个水平分组条形图,显示两组 1 和 2 以及所有三列。列应按“le”、“la”和“lu”的顺序出现。

我自然会用 Hvplot 试试这个:

df.hvplot.barh(x = "group", y = ["le", "la", "lu"])

这样我得到以下结果:

Hvplot 似乎并不关心我添加列的顺序(调用 df.hvplot.barh(x = "group", y = ["lu", "le", "la"]) 不会改变任何东西。Hvplot 似乎也不关心数据框中的原始顺序。

是否有任何选项可以影响条形的顺序?

【问题讨论】:

    标签: python bokeh holoviews hvplot holoviz


    【解决方案1】:

    对于普通条形图,您可以按照您希望的方式对数据进行排序。
    但是,对于分组条形图,您还不能设置顺序。
    但此功能的开发正在进行中,可能会在下一个版本中提供:https://github.com/holoviz/holoviews/issues/3799

    当前使用 Hvplot 0.5.2 和 Holoviews 1.12 的解决方案:
    1) 如果您使用的是 Bokeh 后端,则可以使用关键字挂钩:

    from itertools import product
    
    # define hook function to set order on bokeh plot
    def set_grouped_barplot_order(plot, element):
        # define you categorical ordering in a list of tuples
        factors = product(['2', '1'], ['le', 'la', 'lu'])
    
        # since you're using horizontal bar set order on y_range.factors
        # if you would have had a normal (vertical) barplot you would use x_range.factors
        plot.state.y_range.factors = [*factors]
    
    # create plot    
    group = df.groupby("group").sum()
    group_plot = group.hvplot.barh(
        x="group",
        y=["le", "la", "lu"],
        padding=0.05,
    )
    
    # apply your special ordering function
    group_plot.opts(hooks=[set_grouped_barplot_order], backend='bokeh')
    

    Hooks 允许您将特定的散景设置应用于您的绘图。您不需要经常使用钩子,但在这种情况下它们非常方便。 文档:
    http://holoviews.org/user_guide/Customizing_Plots.html#Plot-hooks
    https://holoviews.org/FAQ.html


    2) 另一种解决方案是将您的 Holoviews 图转换为实际散景图,然后设置排序:

    from itertools import product
    import holoviews as hv
    from bokeh.plotting import show
    
    # create plot
    group = df.groupby("group").sum()
    group_plot = group.hvplot.barh(
        x="group",
        y=["le", "la", "lu"],
        padding=0.05,
    )
    
    # render your holoviews plot as a bokeh plot
    my_bokeh_plot = hv.render(group_plot, backend='bokeh')
    
    # set the custom ordering on your bokeh plot
    factors = product(['2', '1'], ['le', 'la', 'lu'])
    my_bokeh_plot.y_range.factors = [*factors]
    
    show(my_bokeh_plot)
    

    我个人更喜欢第一种解决方案,因为它保留在 Holoviews 中。

    结果图:

    【讨论】:

      【解决方案2】:

      这刚刚在 HoloViews 1.13 中修复。

      您可以按照自己的意愿对条形图进行排序:

      df.hvplot.barh(x="group", y=["lu", "la", "le"])
      


      在我撰写本文时,HoloViews 1.13 尚未正式发布,但您可以通过以下方式安装它:

      pip install git+https://github.com/holoviz/holoviews.git


      如果您想进一步控制订单,可以在 grouped_barplot 上使用 .redim.values():

      group_specific_order = [2, 1]
      variable_specific_order = ['lu', 'la', 'le']
      
      # Note that group and Variable are the variable names of your dimensions here
      # when you use this on a different grouped barchart, then please change to the 
      # names of your own dimensions.
      your_grouped_barplot.redim.values(
          group=group_specific_order, 
          Variable=variable_specific_order,
      )
      

      【讨论】:

      • 我会将此答案标记为正确 - 虽然我知道我对解决方法很满意
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-02
      • 2018-03-16
      • 1970-01-01
      • 2020-10-18
      • 2020-01-08
      • 1970-01-01
      • 2023-03-08
      相关资源
      最近更新 更多