NovoNordisk Production Process Monitoring in Real-Time
Prerrequisites
# !pip install plotly==4.10.0
Simulation
import random
# 3 and 5 are final products
products = ['1', '2', '3', '4', '5']
real_production_rates = {'1': 3 , '2': 4, '3': 2, '4': 2, '5': 3}
stock = {}
formulas = {'3': {'2': 2, '1': 1}, '5': {'4': 4 }}
stock = {0: {product: 0 for product in products}}
def produce(t, stock=stock):
stock[t] = stock[t-1].copy()
production = {}
for product in products:
production[product] = random.randrange(real_production_rates[product])
if product not in formulas.keys():
stock[t][product] += production[product]
for final_product in formulas.keys():
final_product_production = min(production[final_product], min(int(stock[t-1][ingredient]/formulas[final_product][ingredient]) for ingredient in formulas[final_product].keys()))
production[final_product] = final_product_production
for ingredient in formulas[final_product].keys():
stock[t][ingredient] -= production[final_product]*formulas[final_product][ingredient]
stock[t][final_product] += production[final_product]
return production
# Production target in products / per t
target = 1
production_per_time = []
for t in range(1, 1000):
production_per_time.append(produce(t))
x = list(stock.keys())
ys_1 = list(i['1'] for i in stock.values())
ys_2 = list(i['2'] for i in stock.values())
ys_3 = list(i['3'] for i in stock.values())
ys_4 = list(i['4'] for i in stock.values())
ys_5 = list(i['5'] for i in stock.values())
Stock in time
import plotly.graph_objects as go
fig = go.Figure()
# Add traces
fig.add_trace(go.Scatter(x=x, y=ys_1,
mode='lines',
name='Stock product 1'))
fig.add_trace(go.Scatter(x=x, y=ys_2,
mode='lines',
name='Stock product 2'))
fig.add_trace(go.Scatter(x=x, y=ys_3,
mode='lines',
name='Stock product 3'))
fig.add_trace(go.Scatter(x=x, y=ys_4,
mode='lines',
name='Stock product 4'))
fig.add_trace(go.Scatter(x=x, y=ys_5,
mode='lines',
name='Stock product 5'))
fig.update_layout(
title="Product Stock per time",
xaxis_title="T",
yaxis_title="Units in Stock",
)
fig.show()
yp_1 = list(i['1'] for i in production_per_time)
yp_2 = list(i['2'] for i in production_per_time)
yp_3 = list(i['3'] for i in production_per_time)
yp_4 = list(i['4'] for i in production_per_time)
yp_5 = list(i['5'] for i in production_per_time)
Production in time
fig = go.Figure()
# Add traces
fig.add_trace(go.Scatter(x=x, y=yp_1,
mode='markers',
name='Production product 1'))
fig.add_trace(go.Scatter(x=x, y=yp_2,
mode='markers',
name='Production product 2'))
fig.add_trace(go.Scatter(x=x, y=yp_3,
mode='markers',
name='Production product 3'))
fig.add_trace(go.Scatter(x=x, y=yp_4,
mode='markers',
name='Production product 4'))
fig.add_trace(go.Scatter(x=x, y=yp_5,
mode='markers',
name='Production product 5'))
fig.update_layout(
title="Product Production per time",
xaxis_title="T",
yaxis_title="Units produced",
)
fig.show()
titles = ['1', '2', '3', '4', '5']
from plotly.subplots import make_subplots
n = 1
fig = make_subplots(rows=10, cols=1)
for product in yp_1, yp_2, yp_3, yp_4, yp_5:
labels = list(set(product))
values = [product.count(i) for i in labels]
fig = go.Figure(data=[go.Pie(labels=labels, values=values)])
title = titles.pop(0)
fig.update_layout(title=f"Product {title} production distribution")
fig.show()
fig = go.Figure(data=[go.Histogram(x=product)])
fig.update_layout(title=f"Product {title} production distribution")
fig.show()
yp1_bin = [1 if y>=1 else 0 for y in yp_1]
yp2_bin = [1 if y>=1 else 0 for y in yp_2]
yp3_bin = [1 if y>=1 else 0 for y in yp_3]
yp4_bin = [1 if y>=1 else 0 for y in yp_4]
yp5_bin = [1 if y>=1 else 0 for y in yp_5]
binarys = {'1': yp1_bin, '2': yp2_bin, '3': yp3_bin, '4': yp4_bin, '5': yp5_bin}
M = []
for p in range(len(yp1_bin)):
row = []
for product in products:
row.append(binarys[product][p])
M.append([row])
Target acomplishment in time
This animation shows if the target of production was acomplished for that specific T
import numpy as np
import plotly.graph_objs as go
N = 1000
fig = go.Figure(data=go.Heatmap(
z=M[0],
x=['1', '2', '3', '4', '5'],
y=['Product'],
hoverongaps = False,
colorscale=[[0, '#FF0000'], [1, '#00FF00']]),
layout=go.Layout(
title="Frame 0",
updatemenus=[dict(
type="buttons",
buttons=[dict(label="Play",
method="animate",
args=[None])])]
),
frames=[go.Frame(data=[go.Heatmap(z=M[i])],
layout=go.Layout(title_text=f"T={i}"))
for i in range(1, len(M)-1)])
fig.update_layout(
title="Production vs Target",
xaxis_title="Product",
yaxis_title="Production",
# zaxis_title='State of the production'
)
fig.show()