【问题标题】:Get the count / sum of number of bars on a floating hbar plot获取浮动 hbar 图上的条数的计数/总和
【发布时间】:2020-05-08 11:18:56
【问题描述】:

我目前正在使用 matplotlib.pyplot 模块绘制 pandas 数据框的浮动水平条形图。

我想知道如何添加一个附加条,其中包含特定段的条的总和/计数。换句话说,从下面的代码和图中,我想构建一个数据框作为输出:

KP 0.0 to KP 0.1  : 1 bar
KP 0.1 to KP 0.5  : 2 bars
KP 0.5 to KP 0.55 : 3 bars
KP 0.55 to KP 0.7 : 2 bars

等等……

问候,

import pandas as pd
import matplotlib.pyplot as plt

#Create the pandas dataframe
d = {'KP_from' : [0.12, 0.84, 0.5, 0.7], 'KP_to' : [0.55, 0.05, 0.8, 0.75]}
df = pd.DataFrame(data = d)

#Create relavant variables for the floating hbar plot
start = df[['KP_from','KP_to']].min(axis = 1)
mid = df[['KP_from','KP_to']].mean(axis = 1)
width = abs(df.KP_from - df.KP_to)
yval = range(df.shape[0])

df['Direction'] = ['->' if df.KP_from.iloc[i] < df.KP_to.iloc[i] else '<-' for i in yval]

#Create the mpl figure : floating hbar plot
plt.figure()
plt.xlabel('KP')
plt.barh(y = yval, left = start, width = width)
#Add direction arrows at the center of the floating hbar
for i in yval:
    plt.annotate(df.Direction.iloc[i], xy = (mid[i], yval[i]), va = 'center', ha = 'center')
plt.show()

【问题讨论】:

    标签: python pandas matplotlib


    【解决方案1】:

    这是另一种方法。正如其他人已经指出的那样,这首先是一个可以在没有条形图的情况下解决的交集问题。

    def is_present(i_start, i_end, start, end):
        return (
            ((start <= i_start) & (end > i_start)) |
            ((start > i_start) & (end <= i_end))
        )
    
    
    # Create the pandas dataframe
    d = {'KP_from': [0.12, 0.84, 0.5, 0.7], 'KP_to': [0.55, 0.05, 0.8, 0.75]}
    
    intervals = sorted(set(d['KP_from'] + d['KP_to']))
    n_bins = [
        sum([is_present(i, j, s, e) for s, e in zip(d['KP_from'], d['KP_to'])])
        for i, j in zip(intervals, intervals[1:])
    ]
    
    for i, j, c in zip(intervals, intervals[1:], n_bins):
        print(f'KP {i} to KP {j} \t: {c} bars')
    

    【讨论】:

      【解决方案2】:

      您的问题实际上归结为计算每个段中有多少条,我是这样做的:

      def create_final(data):
      
          data = [(x[0],x[1]) if x[0]<x[1] else (x[1],x[0]) for x in data]
      
          ans = []
      
          points = [(i[0], 'init') for i in data] + [(i[1], 'end') for i in data]
      
          points = sorted(points)
      
          carry = points[0]
          nums = 1
          for i in range(1, len(points)):
      
              ans.append((carry[0], points[i][0], nums))
      
              if points[i][1] == 'init':
                  nums+=1
      
              elif points[i][1]=='end':
                  nums-=1
      
              carry = points[i]
      
          return ans
      
      data = [tuple(x) for x in df[['KP_from', 'KP_to']].values]
      
      create_final(data)
      [(0.05, 0.12, 1),
       (0.12, 0.5, 2),
       (0.5, 0.55, 3),
       (0.55, 0.7, 2),
       (0.7, 0.75, 3),
       (0.75, 0.8, 2),
       (0.8, 0.84, 1)]
      
      

      我不知道你想要什么格式,但是从这个元组列表(start, end, number of bars)你可以画出你想要的。

      【讨论】:

        【解决方案3】:

        这更像是一个交集问题:

        # the bar's endpoints in correct order
        data = np.sort(df.values, axis=1)
        
        # The limits of interest -- update the limits as you want
        limits = [0, 0.1, 0.5, 0.55, 0.7]
        limits_data = np.array([[limits[i], limits[i+1]] for i in range(len(limits)-1)])
        
        # intersections
        intersect = (np.maximum(data[:,None, 0], limits_data[:, 0]) <
                     np.minimum(data[:,1,None], limits_data[:,1]) )
        
        
        # count intersections by limit points
        counts = intersect.sum(0)
        

        输出:

        array([1, 2, 3, 2])
        

        要获得预期的打印输出:

        for count, (x,y) in zip(counts, limits_data):
            print(f'KP {x} to KP {y}  : {count} bar(s)')
        

        输出:

        KP 0.0 to KP 0.1  : 1 bar(s)
        KP 0.1 to KP 0.5  : 2 bar(s)
        KP 0.5 to KP 0.55  : 3 bar(s)
        KP 0.55 to KP 0.7  : 2 bar(s)
        

        【讨论】:

        • 我喜欢你的方法,但结果并不完整。应该是[1, 2, 3, 2, 3, 2, 1]
        • 啊非易失性。我注意到您没有包括所有限制。
        猜你喜欢
        • 2011-12-15
        • 2022-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-22
        • 1970-01-01
        相关资源
        最近更新 更多