{"cells":[{"metadata":{},"cell_type":"markdown","source":"In this notebook I would like to show some simple visualization and plotting functions for those getting started as I explore the data. This can be used to create and validate new data, and help understand the problem, visualizing progression stages of the Game of Life."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom IPython.display import clear_output\nimport pandas as pd\nfrom PIL import Image\nimport time","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"size = 25","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Rules for updating**"},{"metadata":{"trusted":true},"cell_type":"code","source":"# from http://jakevdp.github.io/blog/2013/08/07/conways-game-of-life/\ndef life_step_1(X):\n    \"\"\"Game of life step using generator expressions\"\"\"\n    nbrs_count = sum(np.roll(np.roll(X, i, 0), j, 1)\n                     for i in (-1, 0, 1) for j in (-1, 0, 1)\n                     if (i != 0 or j != 0))\n    return (nbrs_count == 3) | (X & (nbrs_count == 2))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def draw_image(img):\n    img = Image.fromarray(np.uint8(img) * 255)\n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_animate(arr):\n    clear_output(wait=True)\n    plt.imshow(draw_image(arr))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Run simulation**"},{"metadata":{"trusted":true},"cell_type":"code","source":"arr = np.random.choice([0,1], (size, size), p=[0.5, 0.5])\nfor x in range(50):\n    arr = life_step_1(arr)\n    plot_animate(arr)\n    if sum(arr.ravel()) == 0:\n        print(x)\n        break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"arr = np.random.choice([0,1], (size, size), p=[0.85, 0.15])\n#warm-up, based on Kaggle desccription\nfor i in range(5):\n    arr = life_step_1(arr)\n# 1 interation\nnew_arr = life_step_1(arr)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Compare plot for start and stop**"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(1,2, figsize=(12,12))\nax[0].imshow(draw_image(arr))\nax[0].set_title('start')\nax[1].imshow(draw_image(new_arr))\nax[1].set_title('stop after 1 iteration')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# WORKING WITH THE DATA\n# parts based on https://www.kaggle.com/candaceng/understanding-the-problem-and-eda","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Load data**"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/conways-reverse-game-of-life-2020/train.csv')\ntest_df = pd.read_csv('/kaggle/input/conways-reverse-game-of-life-2020/test.csv')\nprint(train_df.shape)\nprint(test_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"See count distribution for number of iteration steps. They are fairly uniformly distributed"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.groupby(['delta']).size()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# SELECTING ONE SAMPLE TO VISUALIZE","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_sample = train_df.sample()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_start = train_sample.loc[:, train_sample.columns.str.startswith('start')]\nsample_stop = train_sample.loc[:, train_sample.columns.str.startswith('stop')]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"start_arr = np.asarray(sample_start).reshape(25, 25)\nstop_arr = np.asarray(sample_stop).reshape(25, 25)\n# time step \ntime_step = train_sample['delta'].values[0]\nprint(time_step)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_comp(arr1, arr2, step):\n    fig, ax = plt.subplots(1,2, figsize=(12,12))\n    ax[0].imshow(draw_image(arr1))\n    ax[0].set_title('start')\n    ax[0].axis('off')\n    ax[1].imshow(draw_image(arr2))\n    ax[1].set_title(f'stop after: {step}')\n    ax[1].axis('off')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_comp(start_arr, stop_arr, time_step)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Play as sequence**"},{"metadata":{"trusted":true},"cell_type":"code","source":"updated_arr = np.copy(start_arr)\nsteps = []\nsteps.append(updated_arr)\nfor x in range(time_step):\n    updated_arr = life_step_1(updated_arr)\n    steps.append(updated_arr)\n    plot_animate(updated_arr)\n    time.sleep(0.2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Display as individual frames**"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, m_axs = plt.subplots(1, len(steps), figsize = (10,20))\nfor c_ax, c_row in zip(m_axs.flatten(), steps):\n    c_ax.imshow(c_row, cmap='gray')\n    c_ax.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# CREATING SINGLE STEP DATASET","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"single_step_df = pd.DataFrame(columns=[train_df.columns])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"start_key = ['start_' + str(i) for i in range(625)]\nstop_key = ['stop_' + str(i) for i in range(625)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"arr = np.random.choice([0,1], (size, size))\n#warm-up, based on Kaggle desccription\nfor i in range(5):\n    arr = life_step_1(arr)\n# 1 interation\nupdate_arr = life_step_1(arr)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_row = np.concatenate((np.array([0]).reshape(1,-1), np.array([1]).reshape(1,-1), arr.reshape(-1, 625).round(0).astype('uint8'), update_arr.reshape(-1, 625).round(0).astype('uint8')), axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"single_step_df = single_step_df.append(pd.DataFrame(new_row, columns=list(single_step_df)), ignore_index=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"single_step_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_comp(np.asarray(single_step_df.loc[0, train_sample.columns.str.startswith('start')]).reshape(25,25),\n          np.asarray(single_step_df.loc[0, train_sample.columns.str.startswith('stop')]).reshape(25,25), 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_comp(arr1, arr2, *args, labels=['']):\n    lst=[]\n    lst.append(arr1)\n    lst.append(arr2)\n    for arg in args:\n        lst.append(arg)\n    n = len(lst)\n    if labels == ['']:\n        labels = labels * n\n    fig, ax = plt.subplots(1,n, figsize=(12,12))\n    for idx in range(n):\n        ax[idx].imshow(draw_image(lst[idx]), cmap='gray')\n        ax[idx].set_title(labels[idx])\n        ax[idx].axis('off')\n\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Probability distribution variations**"},{"metadata":{"trusted":true},"cell_type":"code","source":"r = list(np.arange(0.05,0.95,0.01))\np = np.around(list(zip(r,np.subtract(1.0,r))), 2)\nind = list(np.arange(len(p)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"choice = np.random.choice(ind)\narr = np.random.choice([0,1], (size, size), p = p[choice])\n#warm-up, based on Kaggle desccription\nfor i in range(5):\n    arr = life_step_1(arr)\n# 1 interation\nupdate_arr = life_step_1(arr)\nprint(p[choice])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_comp(arr, update_arr)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(10000):\n    arr = np.random.choice([0,1], (size, size), p = p[np.random.choice(ind)])\n    #warm-up, based on Kaggle desccription\n    for i in range(5):\n        arr = life_step_1(arr)\n    # 1 interation\n    update_arr = life_step_1(arr)\n\n    new_row = np.concatenate((np.array([len(single_step_df)]).reshape(1,-1), np.array([1]).reshape(1,-1), arr.reshape(-1, 625).round(0).astype('uint8'), update_arr.reshape(-1, 625).round(0).astype('uint8')), axis=1)\n    single_step_df = single_step_df.append(pd.DataFrame(new_row, columns=list(single_step_df)), ignore_index=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"single_step_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, m_axs = plt.subplots(5, 2, figsize=(12,12))\nfor i, (c_ax, c_row) in enumerate(zip(m_axs.flatten(), single_step_df.sample(5).iterrows())):\n    \n    m_axs[i,0].imshow(np.asarray(c_row[1][627:]).reshape(25,25).astype('uint8'))\n    m_axs[i,0].set_title(c_row[0])\n    m_axs[i,0].axis('off')\n    \n    m_axs[i,1].imshow(np.asarray(c_row[1][2:627]).reshape(25,25).astype('uint8'))\n    m_axs[i,1].set_title(c_row[0])\n    m_axs[i,1].axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(1, 1, figsize=(6,6))\nnum_bins = 50\n\ndelta = 1\ncounts = single_step_df.iloc[:, 627:][single_step_df.iloc[:, 627:] == 1].count(axis=1).values\nax.hist(counts, num_bins, density=True, label=f'{delta}', alpha=0.5)\n\nax.set_xlabel('Number of Alive Cells')\nax.set_ylabel('Probability density')\nax.legend(prop={'size': 10})    \nfig.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"single_step_df.shape # current amount","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}