【问题标题】:Dynamic histogram subplots with line to mark target用线标记目标的动态直方图子图
【发布时间】:2019-02-06 06:54:37
【问题描述】:

我一直在尝试发布一些类似的解决方案,但没有成功。

我正在尝试为我们制造过程中的所有Step No 获取Cost 的直方图。每个部分有不同数量的步骤,所以我想在每个部分的一个图/图像上有一组直方图。

在我的真实数据中有很多部分,所以如果这可以遍历很多部分并保存理想的图表。

此外,我们对要覆盖在直方图上的每个步骤都有一个目标成本。这在一个单独的数据框中表示。我陷入了子图的循环中,所以我还没有尝试过。

以下是我能找到的每个步骤直方图应该是什么样子的:

到目前为止,这是我的代码:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_excel('Dist_Example.xlsx')
df1 = df[~df['Cost Type'].isin(['Material'])]
number_of_subplots = len(df1['Step No'].unique())
steps = df1['Step No'].unique()
fig, axs = plt.subplots(1, number_of_subplots, sharey = True, tight_layout=True)
for step in steps:
    df2 = df1[df1['Step No'].isin([step])]
    axs[step].hist(df2['Cost'])
plt.show()

提前感谢您帮助我!

这是Target Cost 我想在直方图上显示为垂直线:

PartNo  StepNo  TargetCost
ABC     10      12
ABC     20      20
ABC     30     13

以下是一些示例历史数据,它们应位于直方图中的 bin 中:

PartNo  SerialNo    StepNo  CostType    Cost
ABC      123        10      Labor       11
ABC      123        10      Material    16
ABC      456        10      Labor       21
ABC      456        10      Material    26
ABC      789        10      Labor       21
ABC      789        10      Material    16
ABC      1011       10      Labor       11
ABC      1011       10      Material    6
ABC      1112       10      Labor       1
ABC      1112       10      Material    -4
ABC      123        20      Labor       11
ABC      123        20      Material    19
ABC      456        20      Labor       24
ABC      456        20      Material    29
ABC      789        20      Labor       24
ABC      789        20      Material    19
ABC      1011       20      Labor       14
ABC      1011       20      Material    9
ABC      1112       20      Labor       4
ABC      1112       20      Material    -1
ABC      123        30      Labor       11
ABC      123        30      Material    13
ABC      456        30      Labor       18
ABC      456        30      Material    23
ABC      789        30      Labor       18
ABC      789        30      Material    13
ABC      1011       30      Labor       8
ABC      1011       30      Material    3
ABC      1112       30      Labor       -2
ABC      1112       30      Material    -7

还有第二个样本数据集:

PartNo  SerialNo    StepNo  CostType    Cost
DEF     Aplha       10  Labor   2
DEF     Zed         10  Labor   3
DEF     Kelly       10  Labor   4
DEF     Aplha       20  Labor   3
DEF     Zed         20  Labor   2
DEF     Kelly       20  Labor   5
DEF     Aplha       30  Labor   6
DEF     Zed         30  Labor   7
DEF     Kelly       30  Labor   5
DEF     Aplha       40  Labor   3
DEF     Zed         40  Labor   4
DEF     Kelly       40  Labor   2
DEF     Aplha       50  Labor   8
DEF     Zed         50  Labor   9
DEF     Kelly       50  Labor   7

【问题讨论】:

  • 我冒昧地编辑了列名,以便使用pd.read_clipboard(sep='\\s+') 更轻松地获取数据集

标签: python-3.x pandas matplotlib subplot


【解决方案1】:

您不会找到直接为您的数据集解决此问题的直方图函数。您需要以适合您需要的方式汇总数据,然后用条形图表示您的发现。

我发现您的目标和数据有点令人困惑,但我想我已经弄清楚了您在给出这些假设之后的目标:

  1. 您希望汇总每个 StepNo 的成本
  2. 成本类型无关
  3. 必须计算总目标成本,因为您要汇总每个 StepNo 中的所有成本。

剧情

编辑

这不是 OP 想要的。经过一番折腾,我们找到了一个似乎可行的解决方案

(来自问题)我正在尝试获取所有步骤号的成本直方图

(来自评论)我实际上想要每个步骤中每个序列号的成本总和的直方图。

由于您必须在直方图中的 y 轴上有 count 或频率,因此您必须以某种有意义的方式聚合数据。下面您将看到每个步骤中每个 SerialNO 的总成本选择的 bin 数量的计数。

结果:

代码:

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.pyplot as plt
import pylab


# Load data in two steps:
# df1 = pd.read_clipboard(sep='\\s+')
# Part No Serial No   Step No Cost Type   Cost
# ABC      123        10      Labor       11
# ABC      123        10      Material    16
# ABC      456        10      Labor       21
# ABC      456        10      Material    26
# ...

# df2 = pd.read_clipboard(sep='\\s+')
# Part No Step No Target Cost
# ABC     10      12
# ABC     20      20
# ABC     30     13

# Cost type and SerialNo irrelevant
df11 = df1.drop(['CostType'] , axis = 1)

# Aggregate by StepNo, find total cost and count
##df12 = df11.groupby(['PartNo', 'StepNo']).agg(['sum', 'count']).reset_index()
df12 = df11.groupby(['PartNo', 'StepNo', 'SerialNo']).agg(['sum', 'count']).reset_index()

df12.columns = ['PartNo', 'StepNo', 'SerialNo', 'Cost', 'Count']
df3 = pd.merge(df2, df12, how = 'left', on = ['PartNo', 'StepNo'])

# Calculate total target cost
df3['TargetTotal'] = df3['TargetCost']*df3['Count']

# pylab.rcParams['figure.figsize'] = (2, 1)

def multiHist(x_data, x_label, bins):

    # Hisrogram setup
    fig, ax = plt.subplots()
    ax.hist(x_data, bins=bins, color='blue', alpha=0.5, histtype='stepfilled')

    # Horizontal line
    x0 = dfs['TargetTotal'].iloc[0]
    ax.axvline(x0, color='red', linewidth=2)

    # Annotation
    ax.annotate('Target: {:0.2f}'.format(x0), xy=(x0, 1), xytext=(-15, 15),
            xycoords=('data', 'axes fraction'), textcoords='offset points',
            horizontalalignment='left', verticalalignment='center',
            arrowprops=dict(arrowstyle='-|>', fc='white', shrinkA=0, shrinkB=0,
                            connectionstyle='angle,angleA=0,angleB=90,rad=10'),)

    # Labels
    ax.set_xlabel(x_label, color = 'grey')
    ax.legend(loc='upper left')
    plt.show()

# Identify and plot  data for each StepNo
for step in df3['StepNo'].unique():
    dfs = df3[df3['StepNo']==step]

    # Data to plot
    cost = dfs['Cost']
    labels = 'Part: ' + dfs['PartNo'].iloc[0] + ', ' 'Step:' + str(dfs['StepNo'].iloc[0])

    # Plot
    multiHist(x_data = cost, x_label = labels, bins = 4)    

【讨论】:

  • 感谢您帮助我和编辑。我实际上想要一个直方图来表示每个步骤中每个序列号的成本总和。应保持步骤顺序,这将是整个零件的一个大 plt。因此,第 10 步、第 20 步、第 30 步将有一个直方图子图共享轴,然后是成本模型成本的垂直水平线。对于最初的问题不够清楚,我深表歉意。
  • 我很乐意再看看它。一些类似于您想要的图表的屏幕截图确实会有所帮助
  • 酷!但我还是有点困惑。我添加了一个屏幕截图,显示 StepNo = 10 的每个 SerialNo 的成本,Part = ABC
  • 非常接近! x 轴是 bin 成本范围(即 10-20、20-30 等),y 轴是该 bin 中序列号的计数(即 3、4、2 等)。我需要使用真实数据中的垃圾箱才能得到正确的结果。有意义吗?
  • 而垂直线将是成本模型成本适合的位置......忘记提及了。
猜你喜欢
  • 1970-01-01
  • 2013-07-26
  • 2015-08-05
  • 2023-04-11
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
相关资源
最近更新 更多