Skip to content

Instantly share code, notes, and snippets.

@kmader
Created August 2, 2018 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmader/2f90b8f94cbb482c445647d49a3f67fd to your computer and use it in GitHub Desktop.
Save kmader/2f90b8f94cbb482c445647d49a3f67fd to your computer and use it in GitHub Desktop.
FunAnnotation.html
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<title>Thebe Lab examples</title>
<link rel="stylesheet" type="text/css" href="index.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js">
</script>
<!-- Configure and load Thebe !-->
<script type="text/x-thebe-config">
{
bootstrap: true,
binderOptions: {
repo: "chestrays/jupyanno",
ref: "data-branch"
},
kernelOptions: {
name: "python3"
}
}
</script>
<script type="text/javascript"
src="https://unpkg.com/thebelab@^0.3.0"></script>
<!-- or to use a local build: -->
<!-- <script type="text/javascript" src="../lib/index.js"></script> -->
</head>
<body>
<h1>Thebe Lab and Jupyter interactive widgets</h1>
<p>This page illustrates a minimal setup to get custom Jupyter interactive
widgets in Thebe Lab.</p>
<p>This requires adding a script tag to load requirejs on
page, for thebelab to be able to load the JavaScript assets for custom
widgets.</p>
<pre data-executable="true" data-language="python">
import os
import ipywidgets as ipw
from glob import glob
import json
import pandas as pd
import numpy as np
from PIL import Image
from itertools import cycle
from io import BytesIO
from time import time
USERNAME=os.environ.get('APPMODE_USER', 'Not logged in')
HOSTNAME=os.environ.get('HOSTNAME', 'anon')
BUTTONS_PER_ROW = 3
BUTTON_WIDTH = "150px"
UNKNOWN_OPTION = 'Unknown'
with open('task.json', 'r') as f:
annotation_task = json.load(f)
annot_df = pd.DataFrame(annotation_task['dataset']['dataframe'])
print('Loaded annotation task', annot_df.shape[0], 'images')
button_ids = annot_df[annotation_task['dataset']['output_labels']].unique().tolist()
if UNKNOWN_OPTION is not None:
button_ids += [UNKNOWN_OPTION]
image_path_dict = {c_path: os.path.join(annotation_task['dataset']['base_image_directory'],
c_path)
for c_path in annot_df[annotation_task['dataset']['image_path']]}
image_keys = list(image_path_dict.keys())
global out_rows
out_rows = []
def submit_label(label_id, label_name):
"""
should be linked to some kind of database
"""
global out_rows
print('Submitting', label_name, 'for', label_id, 'from', USERNAME, 'part of', HOSTNAME, '@', time())
out_rows += [dict(label_name=label_name, label_id=label_id, user=USERNAME, session=HOSTNAME, time=time())]
return pd.DataFrame(out_rows).to_html()
title_box = ipw.HTML(value=f'<h1> Welcome {USERNAME}</h1><h2> Select the most appropriate label for the given image')
cur_image_view = ipw.Image(layout=ipw.Layout(width="512px"),
disabled=True)
cur_img_id = ipw.Text(layout=ipw.Layout(width="64px"),
disabled=True)
annot_results = ipw.HTML(value='')
SESSION_ID = None
np.random.shuffle(image_keys)
image_iter = cycle(iter(image_keys))
def get_next_image():
c_key = next(image_iter)
cur_img_id.value = c_key
c_img = Image.open(image_path_dict[c_key])
bio_obj = BytesIO()
c_img.save(bio_obj, format='png')
bio_obj.seek(0)
cur_image_view.value=bio_obj.read()
def on_click(btn):
if btn is not None:
annot_results.value = submit_label(cur_img_id.value, btn.description)
get_next_image()
def mk_btn(description):
btn = ipw.Button(description=description, layout=ipw.Layout(width=BUTTON_WIDTH))
btn.on_click(on_click)
return btn
rows = []
c_row = []
for i, but_name in enumerate(button_ids, 1):
c_row+=[mk_btn(but_name)]
if (i % BUTTONS_PER_ROW)==0:
rows+=[ipw.HBox(c_row)]
c_row=[]
rows+=[ipw.HBox(c_row)]
on_click(None) # initialize
ipw.VBox((title_box, cur_image_view)+tuple(rows)+(annot_results,))
</pre>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment