<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Descripción del software
Diagrama de Estados
<img src="https
Step1:  Se crean las estructuras (data frames) que almacenan los datos de los tiempos de ejecución para ambas grillas
Step2:  A partir de las data frames, se crean arreglos que contienen los datos datos que se van a graficar. El parámetro independiente es el número de threads, que se almacena en el arreglo "threads". Por otro lado, los arreglos "time_exec_128x128" y "time_exec_256x256" almacenan los tiempos de ejecución para cada tiempo de simulación, ordenados por cantidad de threads.
Step3:  Finalmente, a través de la función "make_figure", se grafican los tiempos de ejecución almacenados de los arreglos anteriores.
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
import numpy as np
import scipy as sp
import plotly.plotly as py
import plotly.figure_factory as ff
import plotly
from plotly.graph_objs import *
plotly.tools.set_credentials_file(username='gastudillo', api_key='OiqcwUGj4Jmtn1KtY6oR')
Explanation: Descripción del software
Diagrama de Estados
<img src="https://raw.githubusercontent.com/gabriel-astudillo/jupyter/master/diagramaEstados.png">
Rendimiento Computacional
Los tiempos de ejecución del programa implementado se midieron a través de la función omp_get_wtime() en los bloques indicados en diagrama de flujo siguiente
<img src="https://raw.githubusercontent.com/gabriel-astudillo/jupyter/master/diag_general.png">
Por cada tamaño de grilla (128x128 y 256x256 pixeles) y por cada "tiempo total de simulación T", con T={2000, 4000, 8000}, se realizaron 10 mediciones, cuyos promedios se almacenaron en los archivos "tejec-128x128.txt" y "tejec-256x256.txt". Estos archivos están disponibles en https://github.com/gabriel-astudillo/jupyter.
El código que permite obtener el gráfico comparativo de los tiempos de ejecución para distintos tamaños de grilla, tiempos de simulación y número de threads, es el siguiente:
End of explanation
header_names = ["threads","T2000Mean","T2000Std","T4000Mean","T4000Std","T8000Mean","T8000Std"]
df_128x128 = pd.read_csv("https://raw.githubusercontent.com/gabriel-astudillo/jupyter/master/tejec-128x128.txt",
                         delim_whitespace = True,
                         header = None, 
                         names = header_names
                        )
df_256x256 = pd.read_csv("https://raw.githubusercontent.com/gabriel-astudillo/jupyter/master/tejec-256x256.txt",
                         delim_whitespace = True,
                         header = None, 
                         names = header_names
                        )
Explanation: Se crean las estructuras (data frames) que almacenan los datos de los tiempos de ejecución para ambas grillas
End of explanation
threads = df_128x128.threads
time_exec_128x128 = [df_128x128.T2000Mean, df_128x128.T4000Mean, df_128x128.T8000Mean]
time_exec_256x256 = [df_256x256.T2000Mean, df_256x256.T4000Mean, df_256x256.T8000Mean]
Explanation: A partir de las data frames, se crean arreglos que contienen los datos datos que se van a graficar. El parámetro independiente es el número de threads, que se almacena en el arreglo "threads". Por otro lado, los arreglos "time_exec_128x128" y "time_exec_256x256" almacenan los tiempos de ejecución para cada tiempo de simulación, ordenados por cantidad de threads.
End of explanation
def make_figure(times_exec_128, times_exec_256):
    trace_2000_128 = {
        "x" : threads,
        "y" : times_exec_128[0],
        "name":'128x128,T=2000',
        "line": {
            "color": "rgb(#ff, #cd, #d2)",
            "width": 3
        }
    }
    
    trace_4000_128 = {
        "x":threads,
        "y" : times_exec_128[1],
        "name":'128x128,T=4000',
        "line": {
            "color": "rgb(#A2, #D5, #F2)", 
            "width": 3
        } 
    }
    
    trace_8000_128 = {
        "x":threads,
        "y" : times_exec_128[2],
        "name":'128x128,T=8000',
        "line": {
            "color": "rgb(#59, #60, #6D)",
            "width": 3
        }
    }
    
    trace_2000_256 = {
        "x" : threads,
        "y" : times_exec_256[0],
        "name":'256x256,T=2000',
        "line": {
            "color": "rgb(#ff, #cd, #d2)",
            "width": 3
        }
    }
    
    trace_4000_256 = {
        "x":threads,
        "y" : times_exec_256[1],
        "name":'256x256,T=4000',
        "line": {
            "color": "rgb(#A2, #D5, #F2)", 
            "width": 3
        } 
    }
    
    trace_8000_256 = {
        "x":threads,
        "y" : times_exec_256[2],
        "name":'256x256,T=8000',
        "line": {
            "color": "rgb(#59, #60, #6D)",
            "width": 3
        }
    }
    
    data = [trace_2000_128, trace_4000_128, trace_8000_128,
            trace_2000_256, trace_4000_256, trace_8000_256]
    
    
    layout = Layout(title="Tiempo de Ejecución por período de simulación<br>para grillas de 128x128 y 256x256 ",
                xaxis=dict(
                    title='Threads',
                    autotick=False,
                    ticks='inside',
                    tick0=0,
                    dtick=1
                ),
                yaxis=dict(
                    title='Tiempo de Ejecución (en segundos)',
                    showline=True,
                    ticks='outside'
                )
               )
    
    fig = Figure(data=data, layout=layout)
    
    return fig
fig_128x128 = make_figure(time_exec_128x128, time_exec_256x256)
#fig_256x256 = make_figure(time_exec_256x256, "256x256")
py.iplot(fig_128x128, filename='time_exec_all')
Explanation: Finalmente, a través de la función "make_figure", se grafican los tiempos de ejecución almacenados de los arreglos anteriores.
End of explanation
<END_TASK>