{"cells":[{"metadata":{"_uuid":"5d739d4dd9e415b3153dcfce594934ad5fabafc4","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nimport bokeh\nimport bokeh.io\nimport bokeh.plotting\nimport bokeh.layouts\n\nimport ipywidgets\n\ninput_path = '../input/'\n#input_path = './'","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2d4887cc80d2165eb01eeada63d51cfc9ae0b221","scrolled":false,"trusted":true},"cell_type":"code","source":"bokeh.io.output_notebook()\nimport sys\nfor name, module in sorted(sys.modules.items()):\n    if name in ['numpy', 'matplotlib', 'pandas', 'ipywidgets']:\n        if hasattr(module, '__version__'): \n            print(name, module.__version__)\n!python --version","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"21938355ae67dc78ec65150d9675c4b7a286ea2a","trusted":true},"cell_type":"code","source":"assert(input_path[-1] == '/')\ntrain_labels = pd.read_csv(input_path + \"train.csv\", index_col=0)\ntrain_labels.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b783cae9e766ab7b2122704e08aeb8187db2d4bb","trusted":true},"cell_type":"code","source":"def to_rgba(img):\n    \"\"\"Convert a microscopy four channel image 0 to 1 encoded to Bokeh's RGBA encoded\n    \n    The protein of interest is visualized in green,\n    while reference markers for microtubules (red),\n    endoplasmic reticulum (yellow) and nucleus (blue) outline the cell.\n    We changed the order putting the red first to match the RGB order.\n    \n    For more information about the images of the Protein Atlas dataset see\n    https://www.proteinatlas.org/humancell/organelle\n    For more information on microscopy image see:\n    https://en.wikipedia.org/wiki/Fluorescence_microscope\n    \n         Parameters\n    ----------\n    img : array of shape (4, x_resolution, y_resolution)\n        If the image has the size 512x512, then the img parameter must have the shape (4, 512, 512).\n        Each of the (512,512) elements of the image is the the overlay image encoded with numbers\n        between 0 and 1 (including). Each number is the intensity of the point where 0 means no intensity\n        and 1 means max intesity. The input channels are in the following order:\n            img[0] is the red channel\n            img[1] is the green channel\n            img[2] is the blue channel\n            img[3] is the yellow channel\n        \n    Returns\n    -------\n    numpy.ndarray of shape (4, x_resolution, y_resolution) and dtype('uint32')\n        The returned array have the four channels encoded as uint32 numbers in the (tricky) byte order\n        expected by Bokeh. The channel 0 takes the color red; 1 takes green; 2 takes blue, and 3 takes\n        the color yellow. The intensity is used as an alpha transparency.\n    \"\"\"\n    assert np.min(img) >= 0\n    assert np.max(img) <= 1\n    new_img = np.left_shift((np.array(img) * 255).astype(np.uint32), 24)\n    view = new_img.view(dtype=np.uint8).reshape((*new_img.shape, 4))\n    view[0, :, :, 0] = 255                         # red\n    view[1, :, :, 1] = 255                         # green\n    view[2, :, :, 2] = 255                         # blue\n    view[3, :, :, 0] = 255; view[3, :, :, 1] = 255 # red + green = yellow\n\n    return new_img","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"87865e227cc4e2712275ad79bb646e141d49d718","trusted":true},"cell_type":"code","source":"locations = {0:  \"Nucleoplasm\",\n             1:  \"Nuclear membrane\",\n             2:  \"Nucleoli\",\n             3:  \"Nucleoli fibrillar center\",\n             4:  \"Nuclear speckles\",\n             5:  \"Nuclear bodies\",\n             6:  \"Endoplasmic reticulum\",\n             7:  \"Golgi apparatus\",\n             8:  \"Peroxisomes\",\n             9:  \"Endosomes\",\n             10: \"Lysosomes\",\n             11: \"Intermediate filaments\",\n             12: \"Actin filaments\",\n             13: \"Focal adhesion sites\",\n             14: \"Microtubules\",\n             15: \"Microtubule ends\",\n             16: \"Cytokinetic bridge\",\n             17: \"Mitotic spindle\",\n             18: \"Microtubule organizing center\",\n             19: \"Centrosome\",\n             20: \"Lipid droplets\",\n             21: \"Plasma membrane\",\n             22: \"Cell junctions\",\n             23: \"Mitochondria\",\n             24: \"Aggresome\",\n             25: \"Cytosol\",\n             26: \"Cytoplasmic bodies\",\n             27: \"Rods & rings\"}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0e8454c61046a83abb17dca6b514c4d6e6e6b95b","trusted":true},"cell_type":"code","source":"%%time\nsamples = train_labels.Target.str.split(expand=True)\nsamples.index = train_labels.index\nsamples.index.name = 'id'\nsamples = pd.DataFrame(samples.stack().reset_index(drop=True, level=1).astype(int), columns=['target'])\nsamples.replace({'target': locations}, inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"52ba0fa22700c54a7fea7fdd8e65b9561f7de0b5","trusted":true},"cell_type":"code","source":"samples.head(20)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4915374ff4106aa86ffbcac481edfa6ca231c7aa","trusted":true},"cell_type":"code","source":"samples[samples.target == 'Nucleoplasm'].head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a7df7d660f634df1854a5e77a6c1716fd4810bcb","trusted":true},"cell_type":"code","source":"samples.reset_index().groupby('target').count()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4ec7061e1afae4d2b3ae25e80c0c0bf4a035a308","trusted":true},"cell_type":"code","source":"def load_img(uuid, path=input_path+'train/'):\n    a = []\n    assert(path[-1] == '/')\n    a.append(plt.imread(path + uuid + '_red.png'))\n    a.append(plt.imread(path + uuid + '_green.png'))\n    a.append(plt.imread(path + uuid + '_blue.png'))\n    a.append(plt.imread(path + uuid + '_yellow.png'))\n    return a\n\n%time r = to_rgba(load_img('02ce0bfa-bbc9-11e8-b2bc-ac1f6b6435d0'))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8d0f6e65c36b732608f56beec828b6d0ed1a2131","trusted":true},"cell_type":"code","source":"%timeit r = to_rgba(load_img('02ce0bfa-bbc9-11e8-b2bc-ac1f6b6435d0'))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0194c38147126aa45a0af275179d16c66473d91a","scrolled":false,"trusted":true},"cell_type":"code","source":"labels = samples.target.unique()\nids = samples[samples.target == labels[0]].reset_index().id.unique()\n\ncurrent_image = ids[0]\nsource = bokeh.models.ColumnDataSource(data=samples)\n\nr = to_rgba(load_img(current_image))\n_, xres, yres = r.shape\npicture = bokeh.plotting.figure(x_range=(0, xres), y_range=(0, yres))\npicture.background_fill_color = 'black'\nticker = bokeh.models.tickers.FixedTicker(ticks=np.arange(0, 512+128, 128))\npicture.xaxis.ticker = ticker\npicture.yaxis.ticker = ticker\npicture.grid.ticker = ticker\nsource = bokeh.models.ColumnDataSource(data={'red':    [r[0]],\n                                             'green':  [r[1]],\n                                             'blue':   [r[2]],\n                                             'yellow': [r[3]]})\nimages = []\nimages.append(picture.image_rgba(image='red', x=0, y=0, dw=xres, dh=yres, source=source))\nimages.append(picture.image_rgba(image='green', x=0, y=0, dw=xres, dh=yres, source=source))\nimages.append(picture.image_rgba(image='blue', x=0, y=0, dw=xres, dh=yres, source=source))\nimages.append(picture.image_rgba(image='yellow', x=0, y=0, dw=xres, dh=yres, source=source))\n\ntext1 = bokeh.models.widgets.Div(text=\"Current image: <br />\" + current_image)\ntags = \"; \".join(samples.loc[current_image].target.values)\ntext2 = bokeh.models.widgets.Div(text=\"Labels: <br />\" + tags)\n\ncallback = bokeh.models.CustomJS(args={'picture':picture}, code='''\\\n    if (picture.background_fill_color == 'white') {\n        picture.background_fill_color = 'black'\n    } else {\n        picture.background_fill_color = 'white'\n    }\n''')\ncheckbox_background = bokeh.models.widgets.CheckboxGroup(labels=[\"Black background\"],\n                                                         active=[0],\n                                                         callback=callback)\n\nbutton_types = ['danger', 'success', 'primary', 'warning']\ncallbacks = []\ntoggles = []\nfor i, label in enumerate([\"Microtubules\", \"Antibody\", \"Nucleus\", \"Endoplasmic Reticulum\"]):\n    callbacks.append(bokeh.models.CustomJS(args={'object': images[i]},\n                                           code='object.visible = !object.visible'))\n    toggles.append(bokeh.models.widgets.Toggle(label=label,\n                                               button_type=button_types[i],\n                                               callback=callbacks[i]))\n\nw = bokeh.layouts.widgetbox(checkbox_background, *toggles, text1, text2)\n\nbokeh.plotting.show(bokeh.layouts.row([picture, w]), notebook_handle=True)\n\ndef update_img(change):\n    if change['type'] != 'change' or change['name'] != 'value':\n        return\n    global images, picture\n    current_image = ids[change.new-1]\n    text1.text = \"Current image: \\n\" + current_image\n    tags = samples.loc[current_image]\n    if tags.size > 1:\n        text2.text =\"Labels: <br />\" + (\"; \".join(tags.target))\n    else:\n        text2.text =\"Labels: <br />\" + tags.target\n    r = to_rgba(load_img(current_image))\n    source.update(data={'red':    [r[0]],\n                        'green':  [r[1]],\n                        'blue':   [r[2]],\n                        'yellow': [r[3]]})\n    bokeh.io.push_notebook()\n\nslider = ipywidgets.IntSlider(\n    value=1,\n    min=1,\n    max=len(ids),\n    step=1,\n    description='Image:',\n    continuous_update=False,\n    orientation='horizontal',\n)\n\nslider.observe(update_img)\n\ndef update_slider(change):\n    if change['type'] != 'change' or change['name'] != 'value':\n        return\n    global ids, slider\n    ids = samples[samples.target == change.new].reset_index().id.unique()\n    slider.max = len(ids)\n    slider.value = 1\n    slider.notify_change({'name': 'value', 'new': 1, 'type': 'change'})\n\nselect = ipywidgets.Select(\n    options=labels,\n    value=labels[0],\n    rows=10,\n    description='Filter'\n)\n\nselect.observe(update_slider)\n\nbox = ipywidgets.Box([slider, select])\nbox","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"90bb2f94a5463652225941b19fe64b6474ae034a"},"cell_type":"markdown","source":"If you run the notebook, you can interact with it using the \"slider\" to select the image filtered by the labeled protein organelle location."}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.5"}},"nbformat":4,"nbformat_minor":1}