From f2c718fc3f2ae69d3ff785ddb25d61df0fc53141 Mon Sep 17 00:00:00 2001 From: SEK1RO Date: Thu, 25 Dec 2025 14:31:23 +0300 Subject: [PATCH] ds: secp256k1, 2 --- ds/25-1/1e/main.cu | 230 +- ds/25-1/1e/op.ptx | 79 +- ds/25-1/1e/secp256k1.cu | 205 ++ ds/25-1/1e/test.py | 11 +- ds/25-1/2/2-03_cugraph.ipynb | 1194 +------ ds/25-1/2/3-03_dbscan.ipynb | 2 +- ds/25-1/2/4-02_find_infected.ipynb | 818 +++++ ds/25-1/2/4-03_nearest_facilities.ipynb | 3718 ++++++++++++++++++++ ds/25-1/2/4-04_identify_risk_factors.ipynb | 1212 +++++++ 9 files changed, 6139 insertions(+), 1330 deletions(-) create mode 100644 ds/25-1/1e/secp256k1.cu create mode 100644 ds/25-1/2/4-02_find_infected.ipynb create mode 100644 ds/25-1/2/4-03_nearest_facilities.ipynb create mode 100644 ds/25-1/2/4-04_identify_risk_factors.ipynb diff --git a/ds/25-1/1e/main.cu b/ds/25-1/1e/main.cu index 378901a..8b401cd 100644 --- a/ds/25-1/1e/main.cu +++ b/ds/25-1/1e/main.cu @@ -1,152 +1,106 @@ -#include -#include +#include -extern "C" __device__ void add_u16( - ulonglong2 *out_c, - ulonglong2 in_a, - ulonglong2 in_b -); - -extern "C" __device__ void sub_u16( - ulonglong2 *out_c, - ulonglong2 in_a, - ulonglong2 in_b -); - -extern "C" __device__ void add_u32( - ulonglong4 *out_c, - ulonglong4 in_a, - ulonglong4 in_b -); - -extern "C" __device__ void sub_u32( - ulonglong4 *out_c, - ulonglong4 in_a, - ulonglong4 in_b -); - -__device__ void mul_u16( - ulonglong2 *out_c, - ulonglong2 in_a, - ulonglong2 in_b -) { - uint64_t ax_ay = in_a.x + in_a.y; - uint64_t bx_by = in_b.x + in_b.y; - uint64_t axbx = in_a.x * in_b.x; - uint64_t ayby = in_a.y * in_b.y; - out_c->x = ax_ay * bx_by - axbx - ayby; - out_c->y = ayby; -} - -__device__ void mul_u32( - ulonglong4 *out_c, - ulonglong4 in_a, - ulonglong4 in_b -) { - auto ax = (ulonglong2 *)&in_a.x; - auto ay = (ulonglong2 *)&in_a.z; - auto bx = (ulonglong2 *)&in_b.x; - auto by = (ulonglong2 *)&in_b.z; - ulonglong2 ax_ay, bx_by, paren, axbx, ayby; - add_u16(&ax_ay, *ax, *ay); - add_u16(&bx_by, *bx, *by); - mul_u16(&paren, ax_ay, bx_by); - mul_u16(&axbx, *ax, *bx); - mul_u16(&ayby, *ay, *by); - sub_u16(&paren, paren, axbx); - sub_u16(&paren, paren, ayby); - out_c->x = paren.x; - out_c->y = paren.y; - out_c->z = ayby.x; - out_c->w = ayby.y; -} - -__device__ bool equ_u16(ulonglong2 a, ulonglong2 b) { - return a.x == b.x && a.y == b.y; -} - -__device__ bool equ_u32(ulonglong4 a, ulonglong4 b) { - return a.x == b.x && - a.y == b.y && - a.z == b.z && - a.w == b.w; -} - -__device__ void print_u16(ulonglong2 a) { - printf("0x%016llx.%016llx\n", a.x, a.y); -} - -__device__ void print_u32(ulonglong4 a) { - printf("0x%016llx.%016llx.%016llx.%016llx\n", a.x, a.y, a.z, a.w); -} - -#define U8_MAX 0xFFFFFFFFFFFFFFFF -#define _U16_MAX {U8_MAX, U8_MAX} -#define _U32_MAX {U8_MAX, U8_MAX, U8_MAX, U8_MAX} - -__global__ void test(bool *passed) { - *passed = false; - { - ulonglong4 a = _U32_MAX; - ulonglong4 b = {0, 0, 0, 1}; - ulonglong4 c = {0, 0, 0, 0}; - add_u32(&a, a, b); - if (!equ_u32(a, c)) { - printf("add_u32 "); - print_u32(a); - return; +template +__global__ void mat_mul(T *A, T *B, T *C, int N, int M, int K) { + __shared__ T sA[TILE_SIZE][TILE_SIZE]; + __shared__ T sB[TILE_SIZE][TILE_SIZE]; + + int bx = blockIdx.x, by = blockIdx.y; + int tx = threadIdx.x, ty = threadIdx.y; + + int row = by * TILE_SIZE + ty; + int col = bx * TILE_SIZE + tx; + + T sum = 0; + + for (int tile = 0; tile < ceil((float)M/TILE_SIZE); tile++) { + if (row < N && (tile * TILE_SIZE + tx) < M) { + sA[ty][tx] = A[row * M + (tile * TILE_SIZE + tx)]; + } else { + sA[ty][tx] = 0; } - } - { - ulonglong4 a = {0, 0, 0, 0}; - ulonglong4 b = {0, 0, 0, 1}; - ulonglong4 c = _U32_MAX; - sub_u32(&a, a, b); - if (!equ_u32(a, c)) { - printf("sub_32 "); - print_u32(a); - return; + + if ((tile * TILE_SIZE + ty) < M && col < K) { + sB[ty][tx] = B[(tile * TILE_SIZE + ty) * K + col]; + } else { + sB[ty][tx] = 0; } - } - { - ulonglong2 a = _U16_MAX; - ulonglong2 b = {0, U8_MAX}; - ulonglong2 c = {U8_MAX, 1}; - mul_u16(&a, a, b); - if (!equ_u16(a, c)) { - printf("mul_16 "); - print_u16(a); - return; + __syncthreads(); + + for (int k = 0; k < TILE_SIZE; k++) { + sum += sA[ty][k] * sB[k][tx]; } + __syncthreads(); } - { - ulonglong4 a = _U32_MAX; - ulonglong4 b = {0, 0, U8_MAX, U8_MAX}; - ulonglong4 c = {U8_MAX, U8_MAX, 0, 1}; - mul_u32(&a, a, b); - if (!equ_u32(a, c)) { - printf("mul_32 "); - print_u32(a); - return; + + if (row < N && col < K) { + C[row * K + col] = sum; + } +} + +#define MAT_TYPE int +#define MAT_FMT "%d\t" +#define N 5 +#define M 7 +#define K 3 +#define A_LEN (N * M) +#define B_LEN (M * K) +#define C_LEN (N * K) +#define A_SIZE (sizeof(MAT_TYPE) * N * M) +#define B_SIZE (sizeof(MAT_TYPE) * M * K) +#define C_SIZE (sizeof(MAT_TYPE) * N * K) + +#include +#include + +template +void mat_print(T *a, const char *fmt, int n, int m) { + for (auto row = 0; row < n; row++) { + for (auto col = 0; col < m; col++) { + printf(fmt, a[row * m + col]); } + printf("\n"); } - *passed = true; } int main() { - bool test_passed, *d_test_passed; - cudaMalloc(&d_test_passed, sizeof(bool)); - - test<<<1, 1>>>(d_test_passed); - cudaDeviceSynchronize(); + std::random_device rd; + std::mt19937 engine(rd()); + std::uniform_int_distribution dist(1, 10); - cudaMemcpy(&test_passed, d_test_passed, sizeof(bool), cudaMemcpyDeviceToHost); - cudaFree(d_test_passed); - - if (!test_passed) { - printf("test not passed\n"); - return 1; + MAT_TYPE buf[A_LEN + B_LEN + C_LEN]; + for (auto i = 0; i < A_LEN + B_LEN; i++) { + buf[i] = dist(engine); } - return 0; + MAT_TYPE *a = buf; + MAT_TYPE *b = a + A_LEN; + MAT_TYPE *c = b + B_LEN; + + printf("\na\n"); + mat_print(a, MAT_FMT, N, M); + printf("\nb\n"); + mat_print(b, MAT_FMT, M, K); + + MAT_TYPE *d_a, *d_b, *d_c; + cudaMalloc(&d_a, A_SIZE); + cudaMalloc(&d_b, B_SIZE); + cudaMalloc(&d_c, C_SIZE); + + cudaMemcpy(d_a, a, A_SIZE, cudaMemcpyHostToDevice); + cudaMemcpy(d_b, b, B_SIZE, cudaMemcpyHostToDevice); + + dim3 blockDim(4, 4); + dim3 threadDim(4, 4); + mat_mul<<>>(d_a, d_b, d_c, N, M, K); + + cudaMemcpy(c, d_c, C_SIZE, cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + + cudaFree(a); + cudaFree(b); + cudaFree(c); + + printf("\nc\n"); + mat_print(c, MAT_FMT, N, K); } \ No newline at end of file diff --git a/ds/25-1/1e/op.ptx b/ds/25-1/1e/op.ptx index 9b608f3..dcb74f8 100644 --- a/ds/25-1/1e/op.ptx +++ b/ds/25-1/1e/op.ptx @@ -36,15 +36,14 @@ ld.param.v2.u64 {%ra1, %ra0}, [in_a]; ld.param.v2.u64 {%rb1, %rb0}, [in_b]; - add.cc.u64 %ra0, %ra0, %rb0; - addc.u64 %ra1, %ra1, %rb1; + sub.cc.u64 %ra0, %ra0, %rb0; + subc.u64 %ra1, %ra1, %rb1; st.v2.u64 [%rdc], {%ra1, %ra0}; ret; } - .visible .func add_u32( .param .b64 out_c, .param .align 16 .b8 in_a[32], @@ -95,4 +94,78 @@ st.v2.u64 [%rdc + 16], {%ra1, %ra0}; ret; +} + +.visible .func mul_lo_u16( + .param .b64 out_c, + .param .align 16 .b8 in_a[16], + .param .align 16 .b8 in_b[16] +) { + .reg .u64 %a, %b, %c, %d, %a_b, %c_d; + .reg .u64 %ac, %bd_hi, %bd_lo, %p; + .reg .b64 %rdc; + + ld.param.b64 %rdc, [out_c]; + + ld.param.v2.u64 {%a, %b}, [in_a]; + ld.param.v2.u64 {%c, %d}, [in_b]; + + mul.lo.u64 %ac, %a, %c; + mul.lo.u64 %bd_lo, %b, %d; + mul.hi.u64 %bd_hi, %b, %d; + + add.u64 %a_b, %a, %b; + add.u64 %c_d, %c, %d; + + mul.lo.u64 %p, %a_b, %c_d; + + sub.u64 %p, %p, %ac; + sub.u64 %p, %p, %bd_lo; + + add.u64 %p, %p, %bd_hi; + + st.v2.u64 [%rdc], {%p, %bd_lo}; + + ret; +} + +.visible .func mul_u16( + .param .b64 out_c_hi, + .param .b64 out_c_lo, + .param .align 16 .b8 in_a[16], + .param .align 16 .b8 in_b[16] +) { + .reg .u64 %a, %b, %c, %d; + .reg .u64 %a_b_hi, %a_b_lo, %c_d_hi, %c_d_lo; + .reg .u64 %p_hi, %p_lo, %p_hi2, %p_lo2; + .reg .u64 %ac_hi, %ac_lo, %bd_hi, %bd_lo; + .reg .b64 %rdc_hi, %rdc_lo; + + ld.param.b64 %rdc_hi, [out_c_hi]; + ld.param.b64 %rdc_lo, [out_c_lo]; + + ld.param.v2.u64 {%a, %b}, [in_a]; + ld.param.v2.u64 {%c, %d}, [in_b]; + + mul.lo.u64 %ac_lo, %a, %c; + mul.hi.u64 %ac_hi, %a, %c; + mul.lo.u64 %bd_lo, %b, %d; + mul.hi.u64 %bd_hi, %b, %d; + + add.cc.u64 %a_b_lo, %a, %b; + addc.u64 %a_b_hi, %a, %b; + add.cc.u64 %c_d_lo, %c, %d; + addc.u64 %c_d_hi, %c, %d; + + mul.lo.u64 %p_lo, %a_b_lo, %c_d_lo; + mul.hi.u64 %p_hi, %a_b_lo, %c_d_lo; + mul.lo.u64 %p_hi2, %a_b_hi, %c_d_hi; + + + + + st.v2.u64 [%rdc_lo], {%p_hi, %p_lo}; + st.v2.u64 [%rdc_hi], {%a_b_lo, %p_hi2}; + + ret; } \ No newline at end of file diff --git a/ds/25-1/1e/secp256k1.cu b/ds/25-1/1e/secp256k1.cu new file mode 100644 index 0000000..7d9c7cf --- /dev/null +++ b/ds/25-1/1e/secp256k1.cu @@ -0,0 +1,205 @@ +#include +#include + +extern "C" __device__ void add_u16( + ulonglong2 *out_c, + ulonglong2 in_a, + ulonglong2 in_b +); + +extern "C" __device__ void sub_u16( + ulonglong2 *out_c, + ulonglong2 in_a, + ulonglong2 in_b +); + +extern "C" __device__ void add_u32( + ulonglong4 *out_c, + ulonglong4 in_a, + ulonglong4 in_b +); + +extern "C" __device__ void sub_u32( + ulonglong4 *out_c, + ulonglong4 in_a, + ulonglong4 in_b +); + +extern "C" __device__ void mul_lo_u16( + ulonglong2 *out_c, + ulonglong2 in_a, + ulonglong2 in_b +); + +extern "C" __device__ void mul_u16( + ulonglong2 *out_c_hi, + ulonglong2 *out_c_lo, + ulonglong2 in_a, + ulonglong2 in_b +); + +__device__ bool equ_u16(ulonglong2 a, ulonglong2 b) { + return a.x == b.x && a.y == b.y; +} + +__device__ bool equ_u32(ulonglong4 a, ulonglong4 b) { + return a.x == b.x && + a.y == b.y && + a.z == b.z && + a.w == b.w; +} + +__device__ int cmp_u32(ulonglong4 a, ulonglong4 b) { + if (a.x < b.x) + return -1; + else if (a.x > b.x) + return 1; + + if (a.y < b.y) + return -1; + else if (a.y > b.y) + return 1; + + if (a.z < b.z) + return -1; + else if (a.z > b.z) + return 1; + + if (a.w < b.w) + return -1; + else if (a.w > b.w) + return 1; + + return 0; +} + +__device__ void mul_lo_u32( + ulonglong4 *out_c, + ulonglong4 in_a, + ulonglong4 in_b +) { + auto a = (ulonglong2 *)&in_a.x; + auto b = (ulonglong2 *)&in_a.z; + auto c = (ulonglong2 *)&in_b.x; + auto d = (ulonglong2 *)&in_b.z; + ulonglong2 a_b, c_d, ac, bd_hi, bd_lo, p; + + mul_lo_u16(&ac, *a, *c); + mul_u16(&bd_hi, &bd_lo, *b, *d); + + add_u16(&a_b, *a, *b); + add_u16(&c_d, *c, *d); + + mul_lo_u16(&p, a_b, c_d); + + sub_u16(&p, p, ac); + sub_u16(&p, p, bd_lo); + add_u16(&p, p, bd_hi); + + out_c->x = p.x; + out_c->y = p.y; + out_c->z = bd_lo.x; + out_c->w = bd_lo.y; +} + +__device__ void print_u16(ulonglong2 a) { + printf("0x%016llx.%016llx\n", a.x, a.y); +} + +__device__ void print_u32(ulonglong4 a) { + printf("0x%016llx.%016llx.%016llx.%016llx\n", a.x, a.y, a.z, a.w); +} + +#define U8_MAX 0xFFFFFFFFFFFFFFFF +#define U16_MAX {U8_MAX, U8_MAX} +#define U32_MAX {U8_MAX, U8_MAX, U8_MAX, U8_MAX} + +__global__ void test(bool *passed) { + *passed = true; + { + ulonglong4 a = U32_MAX; + ulonglong4 b = {0, 0, 0, 1}; + ulonglong4 c = {0, 0, 0, 0}; + add_u32(&a, a, b); + if (!equ_u32(a, c)) { + printf("add_u32\n"); + print_u32(a); + *passed = false; + } + } + { + ulonglong4 a = {0, 0, 0, 0}; + ulonglong4 b = {0, 0, 0, 1}; + ulonglong4 c = U32_MAX; + sub_u32(&a, a, b); + if (!equ_u32(a, c)) { + printf("sub_u32\n"); + print_u32(a); + *passed = false; + } + } + { + ulonglong2 a = U16_MAX; + ulonglong2 b = {0, U8_MAX}; + ulonglong2 c = {U8_MAX, 1}; + mul_lo_u16(&a, a, b); + if (!equ_u16(a, c)) { + printf("mul_lo_u16\n"); + print_u16(a); + *passed = false; + } + } + { + ulonglong2 a = U16_MAX; + ulonglong2 b = {0, U8_MAX}; + ulonglong2 c_hi = {0, U8_MAX - 1}; + ulonglong2 c_lo = {U8_MAX, 1}; + mul_u16(&a, &b, a, b); + if (!equ_u16(a, c_hi) || !equ_u16(b, c_lo)) { + printf("mul_u16\n"); + print_u16(a); + print_u16(b); + *passed = false; + } + a = U16_MAX; + b = U16_MAX; + c_hi = {U8_MAX, U8_MAX - 1}; + c_lo = {0, 1}; + mul_u16(&a, &b, a, b); + if (!equ_u16(a, c_hi) || !equ_u16(b, c_lo)) { + printf("mul_u16\n"); + print_u16(a); + print_u16(b); + *passed = false; + } + } + { + ulonglong4 a = U32_MAX; + ulonglong4 b = {0, 0, U8_MAX, U8_MAX}; + ulonglong4 c = {U8_MAX, U8_MAX, 0, 1}; + mul_lo_u32(&a, a, b); + if (!equ_u32(a, c)) { + printf("mul_lo_u32\n"); + print_u32(a); + *passed = false; + } + } +} + +int main() { + bool test_passed, *d_test_passed; + cudaMalloc(&d_test_passed, sizeof(bool)); + + test<<<1, 1>>>(d_test_passed); + cudaDeviceSynchronize(); + + cudaMemcpy(&test_passed, d_test_passed, sizeof(bool), cudaMemcpyDeviceToHost); + cudaFree(d_test_passed); + + if (!test_passed) { + printf("test not passed\n"); + return 1; + } + + return 0; +} diff --git a/ds/25-1/1e/test.py b/ds/25-1/1e/test.py index e7f1e14..511579b 100644 --- a/ds/25-1/1e/test.py +++ b/ds/25-1/1e/test.py @@ -2,16 +2,21 @@ U8_MAX = 0xFFFFFFFFFFFFFFFF U16_MAX = U8_MAX << 64 | U8_MAX U32_MAX = U16_MAX << 128 | U16_MAX + def dothex(num): strhex = hex(num)[2:] dothex = strhex[-16:] strhex = strhex[:-16] - + while len(strhex) > 0: dothex = strhex[-16:] + '.' + dothex strhex = strhex[:-16] return '0x' + dothex -print('mul16', dothex(U16_MAX * 2 % (U16_MAX + 1))) -print('mul32', dothex(U32_MAX * U16_MAX % (U32_MAX + 1))) \ No newline at end of file +print('mul_u16', dothex((U16_MAX * U8_MAX >> 128) % + (U16_MAX + 1)), dothex(U16_MAX * U8_MAX % (U16_MAX + 1))) +print('mul_u16', dothex((U16_MAX * U16_MAX >> 128) % + (U16_MAX + 1)), dothex(U16_MAX * U16_MAX % (U16_MAX + 1))) +print('mul_lo_u32', dothex(U32_MAX * U16_MAX % (U32_MAX + 1))) +print('div_lo_u32', dothex(U32_MAX // U8_MAX), dothex(U32_MAX - U32_MAX // U8_MAX)) diff --git a/ds/25-1/2/2-03_cugraph.ipynb b/ds/25-1/2/2-03_cugraph.ipynb index f46299e..7918d05 100644 --- a/ds/25-1/2/2-03_cugraph.ipynb +++ b/ds/25-1/2/2-03_cugraph.ipynb @@ -937,7 +937,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1397,604 +1397,16 @@ }, { "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = true;\n", - " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", - " const reloading = false;\n", - " const Bokeh = root.Bokeh;\n", - "\n", - " // Set a timeout for this load but only if we are not already initializing\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks;\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - " if (js_modules == null) js_modules = [];\n", - " if (js_exports == null) js_exports = {};\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - "\n", - " if (root._bokeh_is_loading > 0) {\n", - " // Don't load bokeh if it is still initializing\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", - " // There is nothing to load\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - " window._bokeh_on_load = on_load\n", - "\n", - " function on_error(e) {\n", - " const src_el = e.srcElement\n", - " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", - " }\n", - "\n", - " const skip = [];\n", - " if (window.requirejs) {\n", - " window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n", - " require([\"h3\"], function(h3) {\n", - " window.h3 = h3\n", - " on_load()\n", - " })\n", - " require([\"deck-gl\"], function(deck) {\n", - " window.deck = deck\n", - " on_load()\n", - " })\n", - " require([\"deck-json\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"loader-csv\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"loader-json\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"loader-tiles\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"mapbox-gl\"], function(mapboxgl) {\n", - " window.mapboxgl = mapboxgl\n", - " on_load()\n", - " })\n", - " require([\"carto\"], function() {\n", - " on_load()\n", - " })\n", - " root._bokeh_is_loading = css_urls.length + 8;\n", - " } else {\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", - " }\n", - "\n", - " const existing_stylesheets = []\n", - " const links = document.getElementsByTagName('link')\n", - " for (let i = 0; i < links.length; i++) {\n", - " const link = links[i]\n", - " if (link.href != null) {\n", - " existing_stylesheets.push(link.href)\n", - " }\n", - " }\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", - " on_load()\n", - " continue;\n", - " }\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " } if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n", - " var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n", - " for (var i = 0; i < urls.length; i++) {\n", - " skip.push(encodeURI(urls[i]))\n", - " }\n", - " } if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n", - " var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n", - " for (var i = 0; i < urls.length; i++) {\n", - " skip.push(encodeURI(urls[i]))\n", - " }\n", - " } var existing_scripts = []\n", - " const scripts = document.getElementsByTagName('script')\n", - " for (let i = 0; i < scripts.length; i++) {\n", - " var script = scripts[i]\n", - " if (script.src != null) {\n", - " existing_scripts.push(script.src)\n", - " }\n", - " }\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (let i = 0; i < js_modules.length; i++) {\n", - " const url = js_modules[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (const name in js_exports) {\n", - " const url = js_exports[name];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " element.textContent = `\n", - " import ${name} from \"${url}\"\n", - " window.${name} = ${name}\n", - " window._bokeh_on_load()\n", - " `\n", - " document.head.appendChild(element);\n", - " }\n", - " if (!js_urls.length && !js_modules.length) {\n", - " on_load()\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/panel.min.js\"];\n", - " const js_modules = [];\n", - " const js_exports = {};\n", - " const css_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.2\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.2\"];\n", - " const inline_js = [ function(Bokeh) {\n", - " inject_raw_css(\"\\n.dataframe table{\\n border: none;\\n}\\n\\n.panel-df table{\\n width: 100%;\\n border-collapse: collapse;\\n border: none;\\n}\\n.panel-df td{\\n white-space: nowrap;\\n overflow: auto;\\n text-overflow: ellipsis;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\"\\n.multi-select{\\n color: white;\\n z-index: 100;\\n background: rgba(44,43,43,0.5);\\n border-radius: 1px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n.multi-select > .bk {\\n padding: 5px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n\\n.deck-chart {\\n z-index: 10;\\n position: initial !important;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\"\\n.center-header {\\n text-align: center\\n}\\n.bk-input-group {\\n padding: 10px;\\n}\\n#sidebar {\\n padding-top: 10px;\\n}\\n.custom-widget-box {\\n margin-top: 20px;\\n padding: 5px;\\n border: None !important;\\n}\\n.custom-widget-box > p {\\n margin: 0px;\\n}\\n.bk-input-group {\\n color: None !important;\\n}\\n.indicator {\\n text-align: center;\\n}\\n.widget-card {\\n margin: 5px 10px;\\n}\\n.number-card {\\n margin: 5px 10px;\\n text-align: center;\\n}\\n.number-card-value {\\n width: 100%;\\n margin: 0px;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " function(Bokeh) {\n", - " (function(root, factory) {\n", - " factory(root[\"Bokeh\"]);\n", - " })(this, function(Bokeh) {\n", - " let define;\n", - " return (function outer(modules, entry) {\n", - " if (Bokeh != null) {\n", - " return Bokeh.register_plugin(modules, entry);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " \"custom/main\": function(require, module, exports) {\n", - " const models = {\n", - " \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n", - " };\n", - " require(\"base\").register_models(models);\n", - " module.exports = models;\n", - " },\n", - " \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var _a;\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n", - " const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n", - " class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n", - " connect_signals() {\n", - " super.connect_signals();\n", - " this.on_change([this.model.properties.active], () => {\n", - " this.model._active = this.model.active;\n", - " });\n", - " }\n", - " }\n", - " exports.CustomInspectToolView = CustomInspectToolView;\n", - " CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n", - " class CustomInspectTool extends inspect_tool_1.InspectTool {\n", - " constructor(attrs) {\n", - " super(attrs);\n", - " }\n", - " }\n", - " exports.CustomInspectTool = CustomInspectTool;\n", - " _a = CustomInspectTool;\n", - " CustomInspectTool.__name__ = \"CustomInspectTool\";\n", - " (() => {\n", - " _a.prototype.default_view = CustomInspectToolView;\n", - " _a.define(({ Boolean }) => ({\n", - " _active: [Boolean, true]\n", - " }));\n", - " _a.register_alias(\"customInspect\", () => new _a());\n", - " })();\n", - " //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n", - " }\n", - " }, \"custom/main\");\n", - " ;\n", - " });\n", - "\n", - " },\n", - "function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " try {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " } catch(e) {\n", - " if (!reloading) {\n", - " throw e;\n", - " }\n", - " }\n", - " }\n", - " // Cache old bokeh versions\n", - " if (Bokeh != undefined && !reloading) {\n", - " var NewBokeh = root.Bokeh;\n", - " if (Bokeh.versions === undefined) {\n", - " Bokeh.versions = new Map();\n", - " }\n", - " if (NewBokeh.version !== Bokeh.version) {\n", - " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", - " }\n", - " root.Bokeh = Bokeh;\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " }\n", - " root._bokeh_is_initializing = false\n", - " }\n", - "\n", - " function load_or_wait() {\n", - " // Implement a backoff loop that tries to ensure we do not load multiple\n", - " // versions of Bokeh and its dependencies at the same time.\n", - " // In recent versions we use the root._bokeh_is_initializing flag\n", - " // to determine whether there is an ongoing attempt to initialize\n", - " // bokeh, however for backward compatibility we also try to ensure\n", - " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", - " // before older versions are fully initialized.\n", - " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", - " // If the timeout and bokeh was not successfully loaded we reset\n", - " // everything and try loading again\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_is_initializing = false;\n", - " root._bokeh_onload_callbacks = undefined;\n", - " root._bokeh_is_loading = 0\n", - " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", - " load_or_wait();\n", - " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", - " setTimeout(load_or_wait, 100);\n", - " } else {\n", - " root._bokeh_is_initializing = true\n", - " root._bokeh_onload_callbacks = []\n", - " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", - " if (!reloading && !bokeh_loaded) {\n", - " if (root.Bokeh) {\n", - " root.Bokeh = undefined;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " }\n", - " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - " }\n", - " // Give older versions of the autoload script a head-start to ensure\n", - " // they initialize before we start loading newer version.\n", - " setTimeout(load_or_wait, 100)\n", - "}(window));" - ], - "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n require([\"h3\"], function(h3) {\n window.h3 = h3\n on_load()\n })\n require([\"deck-gl\"], function(deck) {\n window.deck = deck\n on_load()\n })\n require([\"deck-json\"], function() {\n on_load()\n })\n require([\"loader-csv\"], function() {\n on_load()\n })\n require([\"loader-json\"], function() {\n on_load()\n })\n require([\"loader-tiles\"], function() {\n on_load()\n })\n require([\"mapbox-gl\"], function(mapboxgl) {\n window.mapboxgl = mapboxgl\n on_load()\n })\n require([\"carto\"], function() {\n on_load()\n })\n root._bokeh_is_loading = css_urls.length + 8;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/panel.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.2\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.2\"];\n const inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n.dataframe table{\\n border: none;\\n}\\n\\n.panel-df table{\\n width: 100%;\\n border-collapse: collapse;\\n border: none;\\n}\\n.panel-df td{\\n white-space: nowrap;\\n overflow: auto;\\n text-overflow: ellipsis;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.multi-select{\\n color: white;\\n z-index: 100;\\n background: rgba(44,43,43,0.5);\\n border-radius: 1px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n.multi-select > .bk {\\n padding: 5px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n\\n.deck-chart {\\n z-index: 10;\\n position: initial !important;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.center-header {\\n text-align: center\\n}\\n.bk-input-group {\\n padding: 10px;\\n}\\n#sidebar {\\n padding-top: 10px;\\n}\\n.custom-widget-box {\\n margin-top: 20px;\\n padding: 5px;\\n border: None !important;\\n}\\n.custom-widget-box > p {\\n margin: 0px;\\n}\\n.bk-input-group {\\n color: None !important;\\n}\\n.indicator {\\n text-align: center;\\n}\\n.widget-card {\\n margin: 5px 10px;\\n}\\n.number-card {\\n margin: 5px 10px;\\n text-align: center;\\n}\\n.number-card-value {\\n width: 100%;\\n margin: 0px;\\n}\\n\");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n (function(root, factory) {\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n let define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n const models = {\n \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n \"use strict\";\n var _a;\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n connect_signals() {\n super.connect_signals();\n this.on_change([this.model.properties.active], () => {\n this.model._active = this.model.active;\n });\n }\n }\n exports.CustomInspectToolView = CustomInspectToolView;\n CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n class CustomInspectTool extends inspect_tool_1.InspectTool {\n constructor(attrs) {\n super(attrs);\n }\n }\n exports.CustomInspectTool = CustomInspectTool;\n _a = CustomInspectTool;\n CustomInspectTool.__name__ = \"CustomInspectTool\";\n (() => {\n _a.prototype.default_view = CustomInspectToolView;\n _a.define(({ Boolean }) => ({\n _active: [Boolean, true]\n }));\n _a.register_alias(\"customInspect\", () => new _a());\n })();\n //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n }\n }, \"custom/main\");\n ;\n });\n\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" + "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = false;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n require([\"h3\"], function(h3) {\n window.h3 = h3\n on_load()\n })\n require([\"deck-gl\"], function(deck) {\n window.deck = deck\n on_load()\n })\n require([\"deck-json\"], function() {\n on_load()\n })\n require([\"loader-csv\"], function() {\n on_load()\n })\n require([\"loader-json\"], function() {\n on_load()\n })\n require([\"loader-tiles\"], function() {\n on_load()\n })\n require([\"mapbox-gl\"], function(mapboxgl) {\n window.mapboxgl = mapboxgl\n on_load()\n })\n require([\"carto\"], function() {\n on_load()\n })\n root._bokeh_is_loading = css_urls.length + 8;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.2.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/panel.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.2\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.2\"];\n const inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n.dataframe table{\\n border: none;\\n}\\n\\n.panel-df table{\\n width: 100%;\\n border-collapse: collapse;\\n border: none;\\n}\\n.panel-df td{\\n white-space: nowrap;\\n overflow: auto;\\n text-overflow: ellipsis;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.multi-select{\\n color: white;\\n z-index: 100;\\n background: rgba(44,43,43,0.5);\\n border-radius: 1px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n.multi-select > .bk {\\n padding: 5px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n\\n.deck-chart {\\n z-index: 10;\\n position: initial !important;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.center-header {\\n text-align: center\\n}\\n.bk-input-group {\\n padding: 10px;\\n}\\n#sidebar {\\n padding-top: 10px;\\n}\\n.custom-widget-box {\\n margin-top: 20px;\\n padding: 5px;\\n border: None !important;\\n}\\n.custom-widget-box > p {\\n margin: 0px;\\n}\\n.bk-input-group {\\n color: None !important;\\n}\\n.indicator {\\n text-align: center;\\n}\\n.widget-card {\\n margin: 5px 10px;\\n}\\n.number-card {\\n margin: 5px 10px;\\n text-align: center;\\n}\\n.number-card-value {\\n width: 100%;\\n margin: 0px;\\n}\\n\");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n (function(root, factory) {\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n let define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n const models = {\n \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n \"use strict\";\n var _a;\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n connect_signals() {\n super.connect_signals();\n this.on_change([this.model.properties.active], () => {\n this.model._active = this.model.active;\n });\n }\n }\n exports.CustomInspectToolView = CustomInspectToolView;\n CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n class CustomInspectTool extends inspect_tool_1.InspectTool {\n constructor(attrs) {\n super(attrs);\n }\n }\n exports.CustomInspectTool = CustomInspectTool;\n _a = CustomInspectTool;\n CustomInspectTool.__name__ = \"CustomInspectTool\";\n (() => {\n _a.prototype.default_view = CustomInspectToolView;\n _a.define(({ Boolean }) => ({\n _active: [Boolean, true]\n }));\n _a.register_alias(\"customInspect\", () => new _a());\n })();\n //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n }\n }, \"custom/main\");\n ;\n });\n\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));", + "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { - "application/javascript": [ - "\n", - "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", - " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", - "}\n", - "\n", - "\n", - " function JupyterCommManager() {\n", - " }\n", - "\n", - " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", - " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " comm_manager.register_target(comm_id, function(comm) {\n", - " comm.on_msg(msg_handler);\n", - " });\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", - " comm.onMsg = msg_handler;\n", - " });\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " console.log(message)\n", - " var content = {data: message.data, comm_id};\n", - " var buffers = []\n", - " for (var buffer of message.buffers || []) {\n", - " buffers.push(new DataView(buffer))\n", - " }\n", - " var metadata = message.metadata || {};\n", - " var msg = {content, buffers, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " })\n", - " }\n", - " }\n", - "\n", - " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", - " if (comm_id in window.PyViz.comms) {\n", - " return window.PyViz.comms[comm_id];\n", - " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", - " if (msg_handler) {\n", - " comm.on_msg(msg_handler);\n", - " }\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", - " comm.open();\n", - " if (msg_handler) {\n", - " comm.onMsg = msg_handler;\n", - " }\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", - " comm_promise.then((comm) => {\n", - " window.PyViz.comms[comm_id] = comm;\n", - " if (msg_handler) {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " var content = {data: message.data};\n", - " var metadata = message.metadata || {comm_id};\n", - " var msg = {content, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " }) \n", - " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", - " return comm_promise.then((comm) => {\n", - " comm.send(data, metadata, buffers, disposeOnDone);\n", - " });\n", - " };\n", - " var comm = {\n", - " send: sendClosure\n", - " };\n", - " }\n", - " window.PyViz.comms[comm_id] = comm;\n", - " return comm;\n", - " }\n", - " window.PyViz.comm_manager = new JupyterCommManager();\n", - " \n", - "\n", - "\n", - "var JS_MIME_TYPE = 'application/javascript';\n", - "var HTML_MIME_TYPE = 'text/html';\n", - "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", - "var CLASS_NAME = 'output';\n", - "\n", - "/**\n", - " * Render data to the DOM node\n", - " */\n", - "function render(props, node) {\n", - " var div = document.createElement(\"div\");\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(div);\n", - " node.appendChild(script);\n", - "}\n", - "\n", - "/**\n", - " * Handle when a new output is added\n", - " */\n", - "function handle_add_output(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - " if (id !== undefined) {\n", - " var nchildren = toinsert.length;\n", - " var html_node = toinsert[nchildren-1].children[0];\n", - " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var scripts = [];\n", - " var nodelist = html_node.querySelectorAll(\"script\");\n", - " for (var i in nodelist) {\n", - " if (nodelist.hasOwnProperty(i)) {\n", - " scripts.push(nodelist[i])\n", - " }\n", - " }\n", - "\n", - " scripts.forEach( function (oldScript) {\n", - " var newScript = document.createElement(\"script\");\n", - " var attrs = [];\n", - " var nodemap = oldScript.attributes;\n", - " for (var j in nodemap) {\n", - " if (nodemap.hasOwnProperty(j)) {\n", - " attrs.push(nodemap[j])\n", - " }\n", - " }\n", - " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", - " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", - " oldScript.parentNode.replaceChild(newScript, oldScript);\n", - " });\n", - " if (JS_MIME_TYPE in output.data) {\n", - " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", - " }\n", - " output_area._hv_plot_id = id;\n", - " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", - " window.PyViz.plot_index[id] = Bokeh.index[id];\n", - " } else {\n", - " window.PyViz.plot_index[id] = null;\n", - " }\n", - " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - "function handle_clear_output(event, handle) {\n", - " var id = handle.cell.output_area._hv_plot_id;\n", - " var server_id = handle.cell.output_area._bokeh_server_id;\n", - " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", - " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", - " if (server_id !== null) {\n", - " comm.send({event_type: 'server_delete', 'id': server_id});\n", - " return;\n", - " } else if (comm !== null) {\n", - " comm.send({event_type: 'delete', 'id': id});\n", - " }\n", - " delete PyViz.plot_index[id];\n", - " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", - " var doc = window.Bokeh.index[id].model.document\n", - " doc.clear();\n", - " const i = window.Bokeh.documents.indexOf(doc);\n", - " if (i > -1) {\n", - " window.Bokeh.documents.splice(i, 1);\n", - " }\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle kernel restart event\n", - " */\n", - "function handle_kernel_cleanup(event, handle) {\n", - " delete PyViz.comms[\"hv-extension-comm\"];\n", - " window.PyViz.plot_index = {}\n", - "}\n", - "\n", - "/**\n", - " * Handle update_display_data messages\n", - " */\n", - "function handle_update_output(event, handle) {\n", - " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", - " handle_add_output(event, handle)\n", - "}\n", - "\n", - "function register_renderer(events, OutputArea) {\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[0]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " events.on('output_added.OutputArea', handle_add_output);\n", - " events.on('output_updated.OutputArea', handle_update_output);\n", - " events.on('clear_output.CodeCell', handle_clear_output);\n", - " events.on('delete.Cell', handle_clear_output);\n", - " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", - "\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " safe: true,\n", - " index: 0\n", - " });\n", - "}\n", - "\n", - "if (window.Jupyter !== undefined) {\n", - " try {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " } catch(err) {\n", - " }\n", - "}\n" - ], - "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" + "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", + "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" @@ -2025,604 +1437,16 @@ }, { "data": { - "application/javascript": [ - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " const force = false;\n", - " const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n", - " const reloading = true;\n", - " const Bokeh = root.Bokeh;\n", - "\n", - " // Set a timeout for this load but only if we are not already initializing\n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks;\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - " if (js_modules == null) js_modules = [];\n", - " if (js_exports == null) js_exports = {};\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - "\n", - " if (root._bokeh_is_loading > 0) {\n", - " // Don't load bokeh if it is still initializing\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n", - " // There is nothing to load\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - " window._bokeh_on_load = on_load\n", - "\n", - " function on_error(e) {\n", - " const src_el = e.srcElement\n", - " console.error(\"failed to load \" + (src_el.href || src_el.src));\n", - " }\n", - "\n", - " const skip = [];\n", - " if (window.requirejs) {\n", - " window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n", - " require([\"h3\"], function(h3) {\n", - " window.h3 = h3\n", - " on_load()\n", - " })\n", - " require([\"deck-gl\"], function(deck) {\n", - " window.deck = deck\n", - " on_load()\n", - " })\n", - " require([\"deck-json\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"loader-csv\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"loader-json\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"loader-tiles\"], function() {\n", - " on_load()\n", - " })\n", - " require([\"mapbox-gl\"], function(mapboxgl) {\n", - " window.mapboxgl = mapboxgl\n", - " on_load()\n", - " })\n", - " require([\"carto\"], function() {\n", - " on_load()\n", - " })\n", - " root._bokeh_is_loading = css_urls.length + 8;\n", - " } else {\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n", - " }\n", - "\n", - " const existing_stylesheets = []\n", - " const links = document.getElementsByTagName('link')\n", - " for (let i = 0; i < links.length; i++) {\n", - " const link = links[i]\n", - " if (link.href != null) {\n", - " existing_stylesheets.push(link.href)\n", - " }\n", - " }\n", - " for (let i = 0; i < css_urls.length; i++) {\n", - " const url = css_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (existing_stylesheets.indexOf(escaped) !== -1) {\n", - " on_load()\n", - " continue;\n", - " }\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " } if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n", - " var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n", - " for (var i = 0; i < urls.length; i++) {\n", - " skip.push(encodeURI(urls[i]))\n", - " }\n", - " } if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n", - " var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n", - " for (var i = 0; i < urls.length; i++) {\n", - " skip.push(encodeURI(urls[i]))\n", - " }\n", - " } var existing_scripts = []\n", - " const scripts = document.getElementsByTagName('script')\n", - " for (let i = 0; i < scripts.length; i++) {\n", - " var script = scripts[i]\n", - " if (script.src != null) {\n", - " existing_scripts.push(script.src)\n", - " }\n", - " }\n", - " for (let i = 0; i < js_urls.length; i++) {\n", - " const url = js_urls[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " const element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (let i = 0; i < js_modules.length; i++) {\n", - " const url = js_modules[i];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " for (const name in js_exports) {\n", - " const url = js_exports[name];\n", - " const escaped = encodeURI(url)\n", - " if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n", - " if (!window.requirejs) {\n", - " on_load();\n", - " }\n", - " continue;\n", - " }\n", - " var element = document.createElement('script');\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.type = \"module\";\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " element.textContent = `\n", - " import ${name} from \"${url}\"\n", - " window.${name} = ${name}\n", - " window._bokeh_on_load()\n", - " `\n", - " document.head.appendChild(element);\n", - " }\n", - " if (!js_urls.length && !js_modules.length) {\n", - " on_load()\n", - " }\n", - " };\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " const js_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\"];\n", - " const js_modules = [];\n", - " const js_exports = {};\n", - " const css_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.2\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.2\"];\n", - " const inline_js = [ function(Bokeh) {\n", - " inject_raw_css(\"\\n.dataframe table{\\n border: none;\\n}\\n\\n.panel-df table{\\n width: 100%;\\n border-collapse: collapse;\\n border: none;\\n}\\n.panel-df td{\\n white-space: nowrap;\\n overflow: auto;\\n text-overflow: ellipsis;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\"\\n.multi-select{\\n color: white;\\n z-index: 100;\\n background: rgba(44,43,43,0.5);\\n border-radius: 1px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n.multi-select > .bk {\\n padding: 5px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n\\n.deck-chart {\\n z-index: 10;\\n position: initial !important;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " inject_raw_css(\"\\n.center-header {\\n text-align: center\\n}\\n.bk-input-group {\\n padding: 10px;\\n}\\n#sidebar {\\n padding-top: 10px;\\n}\\n.custom-widget-box {\\n margin-top: 20px;\\n padding: 5px;\\n border: None !important;\\n}\\n.custom-widget-box > p {\\n margin: 0px;\\n}\\n.bk-input-group {\\n color: None !important;\\n}\\n.indicator {\\n text-align: center;\\n}\\n.widget-card {\\n margin: 5px 10px;\\n}\\n.number-card {\\n margin: 5px 10px;\\n text-align: center;\\n}\\n.number-card-value {\\n width: 100%;\\n margin: 0px;\\n}\\n\");\n", - " }, function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " function(Bokeh) {\n", - " (function(root, factory) {\n", - " factory(root[\"Bokeh\"]);\n", - " })(this, function(Bokeh) {\n", - " let define;\n", - " return (function outer(modules, entry) {\n", - " if (Bokeh != null) {\n", - " return Bokeh.register_plugin(modules, entry);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " \"custom/main\": function(require, module, exports) {\n", - " const models = {\n", - " \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n", - " };\n", - " require(\"base\").register_models(models);\n", - " module.exports = models;\n", - " },\n", - " \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var _a;\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n", - " const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n", - " class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n", - " connect_signals() {\n", - " super.connect_signals();\n", - " this.on_change([this.model.properties.active], () => {\n", - " this.model._active = this.model.active;\n", - " });\n", - " }\n", - " }\n", - " exports.CustomInspectToolView = CustomInspectToolView;\n", - " CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n", - " class CustomInspectTool extends inspect_tool_1.InspectTool {\n", - " constructor(attrs) {\n", - " super(attrs);\n", - " }\n", - " }\n", - " exports.CustomInspectTool = CustomInspectTool;\n", - " _a = CustomInspectTool;\n", - " CustomInspectTool.__name__ = \"CustomInspectTool\";\n", - " (() => {\n", - " _a.prototype.default_view = CustomInspectToolView;\n", - " _a.define(({ Boolean }) => ({\n", - " _active: [Boolean, true]\n", - " }));\n", - " _a.register_alias(\"customInspect\", () => new _a());\n", - " })();\n", - " //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n", - " }\n", - " }, \"custom/main\");\n", - " ;\n", - " });\n", - "\n", - " },\n", - "function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (let i = 0; i < inline_js.length; i++) {\n", - " try {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " } catch(e) {\n", - " if (!reloading) {\n", - " throw e;\n", - " }\n", - " }\n", - " }\n", - " // Cache old bokeh versions\n", - " if (Bokeh != undefined && !reloading) {\n", - " var NewBokeh = root.Bokeh;\n", - " if (Bokeh.versions === undefined) {\n", - " Bokeh.versions = new Map();\n", - " }\n", - " if (NewBokeh.version !== Bokeh.version) {\n", - " Bokeh.versions.set(NewBokeh.version, NewBokeh)\n", - " }\n", - " root.Bokeh = Bokeh;\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " }\n", - " root._bokeh_is_initializing = false\n", - " }\n", - "\n", - " function load_or_wait() {\n", - " // Implement a backoff loop that tries to ensure we do not load multiple\n", - " // versions of Bokeh and its dependencies at the same time.\n", - " // In recent versions we use the root._bokeh_is_initializing flag\n", - " // to determine whether there is an ongoing attempt to initialize\n", - " // bokeh, however for backward compatibility we also try to ensure\n", - " // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n", - " // before older versions are fully initialized.\n", - " if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n", - " // If the timeout and bokeh was not successfully loaded we reset\n", - " // everything and try loading again\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_is_initializing = false;\n", - " root._bokeh_onload_callbacks = undefined;\n", - " root._bokeh_is_loading = 0\n", - " console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n", - " load_or_wait();\n", - " } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n", - " setTimeout(load_or_wait, 100);\n", - " } else {\n", - " root._bokeh_is_initializing = true\n", - " root._bokeh_onload_callbacks = []\n", - " const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n", - " if (!reloading && !bokeh_loaded) {\n", - " if (root.Bokeh) {\n", - " root.Bokeh = undefined;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " }\n", - " load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - " }\n", - " // Give older versions of the autoload script a head-start to ensure\n", - " // they initialize before we start loading newer version.\n", - " setTimeout(load_or_wait, 100)\n", - "}(window));" - ], - "application/vnd.holoviews_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = false;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = true;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n require([\"h3\"], function(h3) {\n window.h3 = h3\n on_load()\n })\n require([\"deck-gl\"], function(deck) {\n window.deck = deck\n on_load()\n })\n require([\"deck-json\"], function() {\n on_load()\n })\n require([\"loader-csv\"], function() {\n on_load()\n })\n require([\"loader-json\"], function() {\n on_load()\n })\n require([\"loader-tiles\"], function() {\n on_load()\n })\n require([\"mapbox-gl\"], function(mapboxgl) {\n window.mapboxgl = mapboxgl\n on_load()\n })\n require([\"carto\"], function() {\n on_load()\n })\n root._bokeh_is_loading = css_urls.length + 8;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.2\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.2\"];\n const inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n.dataframe table{\\n border: none;\\n}\\n\\n.panel-df table{\\n width: 100%;\\n border-collapse: collapse;\\n border: none;\\n}\\n.panel-df td{\\n white-space: nowrap;\\n overflow: auto;\\n text-overflow: ellipsis;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.multi-select{\\n color: white;\\n z-index: 100;\\n background: rgba(44,43,43,0.5);\\n border-radius: 1px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n.multi-select > .bk {\\n padding: 5px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n\\n.deck-chart {\\n z-index: 10;\\n position: initial !important;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.center-header {\\n text-align: center\\n}\\n.bk-input-group {\\n padding: 10px;\\n}\\n#sidebar {\\n padding-top: 10px;\\n}\\n.custom-widget-box {\\n margin-top: 20px;\\n padding: 5px;\\n border: None !important;\\n}\\n.custom-widget-box > p {\\n margin: 0px;\\n}\\n.bk-input-group {\\n color: None !important;\\n}\\n.indicator {\\n text-align: center;\\n}\\n.widget-card {\\n margin: 5px 10px;\\n}\\n.number-card {\\n margin: 5px 10px;\\n text-align: center;\\n}\\n.number-card-value {\\n width: 100%;\\n margin: 0px;\\n}\\n\");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n (function(root, factory) {\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n let define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n const models = {\n \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n \"use strict\";\n var _a;\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n connect_signals() {\n super.connect_signals();\n this.on_change([this.model.properties.active], () => {\n this.model._active = this.model.active;\n });\n }\n }\n exports.CustomInspectToolView = CustomInspectToolView;\n CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n class CustomInspectTool extends inspect_tool_1.InspectTool {\n constructor(attrs) {\n super(attrs);\n }\n }\n exports.CustomInspectTool = CustomInspectTool;\n _a = CustomInspectTool;\n CustomInspectTool.__name__ = \"CustomInspectTool\";\n (() => {\n _a.prototype.default_view = CustomInspectToolView;\n _a.define(({ Boolean }) => ({\n _active: [Boolean, true]\n }));\n _a.register_alias(\"customInspect\", () => new _a());\n })();\n //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n }\n }, \"custom/main\");\n ;\n });\n\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));" + "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = false;\n const py_version = '3.5.2'.replace('rc', '-rc.').replace('.dev', '-dev.');\n const reloading = true;\n const Bokeh = root.Bokeh;\n\n // Set a timeout for this load but only if we are not already initializing\n if (typeof (root._bokeh_timeout) === \"undefined\" || (force || !root._bokeh_is_initializing)) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n // Don't load bokeh if it is still initializing\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n } else if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n // There is nothing to load\n run_callbacks();\n return null;\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error(e) {\n const src_el = e.srcElement\n console.error(\"failed to load \" + (src_el.href || src_el.src));\n }\n\n const skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'h3': 'https://cdn.jsdelivr.net/npm/h3-js@4.1.0/dist/h3-js.umd', 'deck-gl': 'https://cdn.jsdelivr.net/npm/deck.gl@9.0.20/dist.min', 'deck-json': 'https://cdn.jsdelivr.net/npm/@deck.gl/json@9.0.20/dist.min', 'loader-csv': 'https://cdn.jsdelivr.net/npm/@loaders.gl/csv@4.2.2/dist/dist.min', 'loader-json': 'https://cdn.jsdelivr.net/npm/@loaders.gl/json@4.2.2/dist/dist.min', 'loader-tiles': 'https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@4.2.2/dist/dist.min', 'mapbox-gl': 'https://api.mapbox.com/mapbox-gl-js/v3.0.1/mapbox-gl', 'carto': 'https://cdn.jsdelivr.net/npm/@deck.gl/carto@^9.0.20/dist.min'}, 'shim': {'deck-json': {'deps': ['deck-gl']}, 'deck-gl': {'deps': ['h3']}}});\n require([\"h3\"], function(h3) {\n window.h3 = h3\n on_load()\n })\n require([\"deck-gl\"], function(deck) {\n window.deck = deck\n on_load()\n })\n require([\"deck-json\"], function() {\n on_load()\n })\n require([\"loader-csv\"], function() {\n on_load()\n })\n require([\"loader-json\"], function() {\n on_load()\n })\n require([\"loader-tiles\"], function() {\n on_load()\n })\n require([\"mapbox-gl\"], function(mapboxgl) {\n window.mapboxgl = mapboxgl\n on_load()\n })\n require([\"carto\"], function() {\n on_load()\n })\n root._bokeh_is_loading = css_urls.length + 8;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n const existing_stylesheets = []\n const links = document.getElementsByTagName('link')\n for (let i = 0; i < links.length; i++) {\n const link = links[i]\n if (link.href != null) {\n existing_stylesheets.push(link.href)\n }\n }\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const escaped = encodeURI(url)\n if (existing_stylesheets.indexOf(escaped) !== -1) {\n on_load()\n continue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window.deck !== undefined) && (!(window.deck instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js', 'https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } if (((window.mapboxgl !== undefined) && (!(window.mapboxgl instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(encodeURI(urls[i]))\n }\n } var existing_scripts = []\n const scripts = document.getElementsByTagName('script')\n for (let i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n existing_scripts.push(script.src)\n }\n }\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (let i = 0; i < js_modules.length; i++) {\n const url = js_modules[i];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) !== -1 || existing_scripts.indexOf(escaped) !== -1) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n const url = js_exports[name];\n const escaped = encodeURI(url)\n if (skip.indexOf(escaped) >= 0 || root[name] != null) {\n if (!window.requirejs) {\n on_load();\n }\n continue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/h3-js@4.1.0/dist/h3-js.umd.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/deck.gl@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/json@9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/csv@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/json@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@loaders.gl/3d-tiles@4.2.2/dist/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl/dist/maplibre-gl.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/@deck.gl/carto@^9.0.20/dist.min.js\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js\"];\n const js_modules = [];\n const js_exports = {};\n const css_urls = [\"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/mapbox-gl-js/v3.0.1/mapbox-gl.css?v=1.5.2\", \"https://cdn.holoviz.org/panel/1.5.2/dist/bundled/deckglplot/maplibre-gl@4.4.1/dist/maplibre-gl.css?v=1.5.2\"];\n const inline_js = [ function(Bokeh) {\n inject_raw_css(\"\\n.dataframe table{\\n border: none;\\n}\\n\\n.panel-df table{\\n width: 100%;\\n border-collapse: collapse;\\n border: none;\\n}\\n.panel-df td{\\n white-space: nowrap;\\n overflow: auto;\\n text-overflow: ellipsis;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.multi-select{\\n color: white;\\n z-index: 100;\\n background: rgba(44,43,43,0.5);\\n border-radius: 1px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n.multi-select > .bk {\\n padding: 5px;\\n width: 120px !important;\\n height: 30px !important;\\n}\\n\\n.deck-chart {\\n z-index: 10;\\n position: initial !important;\\n}\\n\");\n }, function(Bokeh) {\n inject_raw_css(\"\\n.center-header {\\n text-align: center\\n}\\n.bk-input-group {\\n padding: 10px;\\n}\\n#sidebar {\\n padding-top: 10px;\\n}\\n.custom-widget-box {\\n margin-top: 20px;\\n padding: 5px;\\n border: None !important;\\n}\\n.custom-widget-box > p {\\n margin: 0px;\\n}\\n.bk-input-group {\\n color: None !important;\\n}\\n.indicator {\\n text-align: center;\\n}\\n.widget-card {\\n margin: 5px 10px;\\n}\\n.number-card {\\n margin: 5px 10px;\\n text-align: center;\\n}\\n.number-card-value {\\n width: 100%;\\n margin: 0px;\\n}\\n\");\n }, function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n (function(root, factory) {\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n let define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n const models = {\n \"CustomInspectTool\": require(\"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\").CustomInspectTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cuxfilter.charts.datashader.custom_extensions.graph_inspect_widget.custom_inspect_tool\": function(require, module, exports) {\n \"use strict\";\n var _a;\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports.CustomInspectTool = exports.CustomInspectToolView = void 0;\n const inspect_tool_1 = require(\"models/tools/inspectors/inspect_tool\");\n class CustomInspectToolView extends inspect_tool_1.InspectToolView {\n connect_signals() {\n super.connect_signals();\n this.on_change([this.model.properties.active], () => {\n this.model._active = this.model.active;\n });\n }\n }\n exports.CustomInspectToolView = CustomInspectToolView;\n CustomInspectToolView.__name__ = \"CustomInspectToolView\";\n class CustomInspectTool extends inspect_tool_1.InspectTool {\n constructor(attrs) {\n super(attrs);\n }\n }\n exports.CustomInspectTool = CustomInspectTool;\n _a = CustomInspectTool;\n CustomInspectTool.__name__ = \"CustomInspectTool\";\n (() => {\n _a.prototype.default_view = CustomInspectToolView;\n _a.define(({ Boolean }) => ({\n _active: [Boolean, true]\n }));\n _a.register_alias(\"customInspect\", () => new _a());\n })();\n //# sourceMappingURL=graph_inspect_widget.py:CustomInspectTool.js.map\n }\n }, \"custom/main\");\n ;\n });\n\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (let i = 0; i < inline_js.length; i++) {\n try {\n inline_js[i].call(root, root.Bokeh);\n } catch(e) {\n if (!reloading) {\n throw e;\n }\n }\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n var NewBokeh = root.Bokeh;\n if (Bokeh.versions === undefined) {\n Bokeh.versions = new Map();\n }\n if (NewBokeh.version !== Bokeh.version) {\n Bokeh.versions.set(NewBokeh.version, NewBokeh)\n }\n root.Bokeh = Bokeh;\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n // If the timeout and bokeh was not successfully loaded we reset\n // everything and try loading again\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n root._bokeh_is_loading = 0\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n const bokeh_loaded = root.Bokeh != null && (root.Bokeh.version === py_version || (root.Bokeh.versions !== undefined && root.Bokeh.versions.has(py_version)));\n if (!reloading && !bokeh_loaded) {\n if (root.Bokeh) {\n root.Bokeh = undefined;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));", + "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { - "application/javascript": [ - "\n", - "if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n", - " window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n", - "}\n", - "\n", - "\n", - " function JupyterCommManager() {\n", - " }\n", - "\n", - " JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n", - " if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " comm_manager.register_target(comm_id, function(comm) {\n", - " comm.on_msg(msg_handler);\n", - " });\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n", - " comm.onMsg = msg_handler;\n", - " });\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " console.log(message)\n", - " var content = {data: message.data, comm_id};\n", - " var buffers = []\n", - " for (var buffer of message.buffers || []) {\n", - " buffers.push(new DataView(buffer))\n", - " }\n", - " var metadata = message.metadata || {};\n", - " var msg = {content, buffers, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " })\n", - " }\n", - " }\n", - "\n", - " JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n", - " if (comm_id in window.PyViz.comms) {\n", - " return window.PyViz.comms[comm_id];\n", - " } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n", - " var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n", - " var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n", - " if (msg_handler) {\n", - " comm.on_msg(msg_handler);\n", - " }\n", - " } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n", - " var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n", - " comm.open();\n", - " if (msg_handler) {\n", - " comm.onMsg = msg_handler;\n", - " }\n", - " } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n", - " var comm_promise = google.colab.kernel.comms.open(comm_id)\n", - " comm_promise.then((comm) => {\n", - " window.PyViz.comms[comm_id] = comm;\n", - " if (msg_handler) {\n", - " var messages = comm.messages[Symbol.asyncIterator]();\n", - " function processIteratorResult(result) {\n", - " var message = result.value;\n", - " var content = {data: message.data};\n", - " var metadata = message.metadata || {comm_id};\n", - " var msg = {content, metadata}\n", - " msg_handler(msg);\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " return messages.next().then(processIteratorResult);\n", - " }\n", - " }) \n", - " var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n", - " return comm_promise.then((comm) => {\n", - " comm.send(data, metadata, buffers, disposeOnDone);\n", - " });\n", - " };\n", - " var comm = {\n", - " send: sendClosure\n", - " };\n", - " }\n", - " window.PyViz.comms[comm_id] = comm;\n", - " return comm;\n", - " }\n", - " window.PyViz.comm_manager = new JupyterCommManager();\n", - " \n", - "\n", - "\n", - "var JS_MIME_TYPE = 'application/javascript';\n", - "var HTML_MIME_TYPE = 'text/html';\n", - "var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n", - "var CLASS_NAME = 'output';\n", - "\n", - "/**\n", - " * Render data to the DOM node\n", - " */\n", - "function render(props, node) {\n", - " var div = document.createElement(\"div\");\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(div);\n", - " node.appendChild(script);\n", - "}\n", - "\n", - "/**\n", - " * Handle when a new output is added\n", - " */\n", - "function handle_add_output(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - " if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - " var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - " if (id !== undefined) {\n", - " var nchildren = toinsert.length;\n", - " var html_node = toinsert[nchildren-1].children[0];\n", - " html_node.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var scripts = [];\n", - " var nodelist = html_node.querySelectorAll(\"script\");\n", - " for (var i in nodelist) {\n", - " if (nodelist.hasOwnProperty(i)) {\n", - " scripts.push(nodelist[i])\n", - " }\n", - " }\n", - "\n", - " scripts.forEach( function (oldScript) {\n", - " var newScript = document.createElement(\"script\");\n", - " var attrs = [];\n", - " var nodemap = oldScript.attributes;\n", - " for (var j in nodemap) {\n", - " if (nodemap.hasOwnProperty(j)) {\n", - " attrs.push(nodemap[j])\n", - " }\n", - " }\n", - " attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n", - " newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n", - " oldScript.parentNode.replaceChild(newScript, oldScript);\n", - " });\n", - " if (JS_MIME_TYPE in output.data) {\n", - " toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n", - " }\n", - " output_area._hv_plot_id = id;\n", - " if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n", - " window.PyViz.plot_index[id] = Bokeh.index[id];\n", - " } else {\n", - " window.PyViz.plot_index[id] = null;\n", - " }\n", - " } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - "function handle_clear_output(event, handle) {\n", - " var id = handle.cell.output_area._hv_plot_id;\n", - " var server_id = handle.cell.output_area._bokeh_server_id;\n", - " if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n", - " var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n", - " if (server_id !== null) {\n", - " comm.send({event_type: 'server_delete', 'id': server_id});\n", - " return;\n", - " } else if (comm !== null) {\n", - " comm.send({event_type: 'delete', 'id': id});\n", - " }\n", - " delete PyViz.plot_index[id];\n", - " if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n", - " var doc = window.Bokeh.index[id].model.document\n", - " doc.clear();\n", - " const i = window.Bokeh.documents.indexOf(doc);\n", - " if (i > -1) {\n", - " window.Bokeh.documents.splice(i, 1);\n", - " }\n", - " }\n", - "}\n", - "\n", - "/**\n", - " * Handle kernel restart event\n", - " */\n", - "function handle_kernel_cleanup(event, handle) {\n", - " delete PyViz.comms[\"hv-extension-comm\"];\n", - " window.PyViz.plot_index = {}\n", - "}\n", - "\n", - "/**\n", - " * Handle update_display_data messages\n", - " */\n", - "function handle_update_output(event, handle) {\n", - " handle_clear_output(event, {cell: {output_area: handle.output_area}})\n", - " handle_add_output(event, handle)\n", - "}\n", - "\n", - "function register_renderer(events, OutputArea) {\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[0]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " events.on('output_added.OutputArea', handle_add_output);\n", - " events.on('output_updated.OutputArea', handle_update_output);\n", - " events.on('clear_output.CodeCell', handle_clear_output);\n", - " events.on('delete.Cell', handle_clear_output);\n", - " events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n", - "\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " safe: true,\n", - " index: 0\n", - " });\n", - "}\n", - "\n", - "if (window.Jupyter !== undefined) {\n", - " try {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " } catch(err) {\n", - " }\n", - "}\n" - ], - "application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n" + "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", + "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" diff --git a/ds/25-1/2/3-03_dbscan.ipynb b/ds/25-1/2/3-03_dbscan.ipynb index 4d4b95b..5278777 100644 --- a/ds/25-1/2/3-03_dbscan.ipynb +++ b/ds/25-1/2/3-03_dbscan.ipynb @@ -227,7 +227,7 @@ } ], "source": [ - "dbscan = cuml.DBSCAN(eps=5000)eps=5000)\n", + "dbscan = cuml.DBSCAN(eps=5000)\n", "# dbscan = cuml.DBSCAN(eps=10000)\n", "\n", "infected_df = gdf[gdf['infected'] == 1].reset_index()\n", diff --git a/ds/25-1/2/4-02_find_infected.ipynb b/ds/25-1/2/4-02_find_infected.ipynb new file mode 100644 index 0000000..2d5feb3 --- /dev/null +++ b/ds/25-1/2/4-02_find_infected.ipynb @@ -0,0 +1,818 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Header\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Week 1: Find Clusters of Infected People" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "**URGENT WARNING**\n", + "\n", + "We have been receiving reports from health facilities that a new, fast-spreading virus has been discovered in the population. To prepare our response, we need to understand the geospatial distribution of those who have been infected. Find out whether there are identifiable clusters of infected individuals and where they are. \n", + "\n", + "\n", + "Your goal for this notebook will be to estimate the location of dense geographic clusters of infected people using incoming data from week 1 of the simulated epidemic." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The cudf.pandas extension is already loaded. To reload it, use:\n", + " %reload_ext cudf.pandas\n" + ] + } + ], + "source": [ + "%load_ext cudf.pandas\n", + "import pandas as pd\n", + "import cuml\n", + "\n", + "import cupy as cp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Begin by loading the data you've received about week 1 of the outbreak into a cuDF-accelerated pandas DataFrame. The data is located at `'./data/week1.csv'`. For this notebook you will only need the `'lat'`, `'long'`, and `'infected'` columns. Either drop the columns after loading, or use the `pd.read_csv` named argument `usecols` to provide a list of only the columns you need." + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latlonginfected
054.522511-1.571896False
154.554031-1.524968False
254.552483-1.435203False
354.537186-1.566215False
454.528210-1.588462False
\n", + "
" + ], + "text/plain": [ + " lat long infected\n", + "0 54.522511 -1.571896 False\n", + "1 54.554031 -1.524968 False\n", + "2 54.552483 -1.435203 False\n", + "3 54.537186 -1.566215 False\n", + "4 54.528210 -1.588462 False" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv('./data/week1.csv', dtype = {\n", + " 'lat': 'float32',\n", + " 'long': 'float32',\n", + " 'infected': 'category',\n", + "}, usecols = ['lat', 'long', 'infected'])\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Make Data Frame of the Infected" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Make a new DataFrame `infected_df` that contains only the infected members of the population.\n", + "\n", + "**Tip**: Reset the index of `infected_df` with `.reset_index(drop=True)`. " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[28928759 28930512 28930904 ... 57410428 57411005 57411919]\n", + "[ 0 1 2 ... 18145 18146 18147]\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latlonginfected
054.472767-1.654932True
154.529720-1.667143True
254.512981-1.589866True
354.522320-1.380694True
454.541656-1.613490True
\n", + "
" + ], + "text/plain": [ + " lat long infected\n", + "0 54.472767 -1.654932 True\n", + "1 54.529720 -1.667143 True\n", + "2 54.512981 -1.589866 True\n", + "3 54.522320 -1.380694 True\n", + "4 54.541656 -1.613490 True" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "infected_df = df[df['infected'] == True]\n", + "print(infected_df.index.values)\n", + "\n", + "infected_df = infected_df.reset_index(drop=True)\n", + "\n", + "print(infected_df.index.values)\n", + "infected_df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Make Grid Coordinates for Infected Locations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Provided for you in the next cell (which you can expand by clicking on the \"...\" and contract again after executing by clicking on the blue left border of the cell) is the lat/long to OSGB36 grid coordinates converter you used earlier in the workshop. Use this converter to create grid coordinate values stored in `northing` and `easting` columns of the `infected_df` you created in the last step." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "# https://www.ordnancesurvey.co.uk/docs/support/guide-coordinate-systems-great-britain.pdf\n", + "\n", + "def latlong2osgbgrid_cupy(lat, long, input_degrees=True):\n", + " '''\n", + " Converts latitude and longitude (ellipsoidal) coordinates into northing and easting (grid) coordinates, using a Transverse Mercator projection.\n", + " \n", + " Inputs:\n", + " lat: latitude coordinate (N)\n", + " long: longitude coordinate (E)\n", + " input_degrees: if True (default), interprets the coordinates as degrees; otherwise, interprets coordinates as radians\n", + " \n", + " Output:\n", + " (northing, easting)\n", + " '''\n", + " \n", + " if input_degrees:\n", + " lat = lat * cp.pi/180\n", + " long = long * cp.pi/180\n", + "\n", + " a = 6377563.396\n", + " b = 6356256.909\n", + " e2 = (a**2 - b**2) / a**2\n", + "\n", + " N0 = -100000 # northing of true origin\n", + " E0 = 400000 # easting of true origin\n", + " F0 = .9996012717 # scale factor on central meridian\n", + " phi0 = 49 * cp.pi / 180 # latitude of true origin\n", + " lambda0 = -2 * cp.pi / 180 # longitude of true origin and central meridian\n", + " \n", + " sinlat = cp.sin(lat)\n", + " coslat = cp.cos(lat)\n", + " tanlat = cp.tan(lat)\n", + " \n", + " latdiff = lat-phi0\n", + " longdiff = long-lambda0\n", + "\n", + " n = (a-b) / (a+b)\n", + " nu = a * F0 * (1 - e2 * sinlat ** 2) ** -.5\n", + " rho = a * F0 * (1 - e2) * (1 - e2 * sinlat ** 2) ** -1.5\n", + " eta2 = nu / rho - 1\n", + " M = b * F0 * ((1 + n + 5/4 * (n**2 + n**3)) * latdiff - \n", + " (3*(n+n**2) + 21/8 * n**3) * cp.sin(latdiff) * cp.cos(lat+phi0) +\n", + " 15/8 * (n**2 + n**3) * cp.sin(2*(latdiff)) * cp.cos(2*(lat+phi0)) - \n", + " 35/24 * n**3 * cp.sin(3*(latdiff)) * cp.cos(3*(lat+phi0)))\n", + " I = M + N0\n", + " II = nu/2 * sinlat * coslat\n", + " III = nu/24 * sinlat * coslat ** 3 * (5 - tanlat ** 2 + 9 * eta2)\n", + " IIIA = nu/720 * sinlat * coslat ** 5 * (61-58 * tanlat**2 + tanlat**4)\n", + " IV = nu * coslat\n", + " V = nu / 6 * coslat**3 * (nu/rho - cp.tan(lat)**2)\n", + " VI = nu / 120 * coslat ** 5 * (5 - 18 * tanlat**2 + tanlat**4 + 14 * eta2 - 58 * tanlat**2 * eta2)\n", + "\n", + " northing = I + II * longdiff**2 + III * longdiff**4 + IIIA * longdiff**6\n", + " easting = E0 + IV * longdiff + V * longdiff**3 + VI * longdiff**5\n", + "\n", + " return(northing, easting)" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latlonginfectednorthingeastingcluster
054.472767-1.654932True508670.609809422359.747233-1
154.529720-1.667143True515003.452959421538.534748-1
254.512981-1.589866True513167.311551426549.871569-1
354.522320-1.380694True514305.528712440081.234190-1
454.541656-1.613490True516349.193146425002.998690-1
\n", + "
" + ], + "text/plain": [ + " lat long infected northing easting cluster\n", + "0 54.472767 -1.654932 True 508670.609809 422359.747233 -1\n", + "1 54.529720 -1.667143 True 515003.452959 421538.534748 -1\n", + "2 54.512981 -1.589866 True 513167.311551 426549.871569 -1\n", + "3 54.522320 -1.380694 True 514305.528712 440081.234190 -1\n", + "4 54.541656 -1.613490 True 516349.193146 425002.998690 -1" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cupy_lat = cp.asarray(infected_df['lat'])\n", + "cupy_long = cp.asarray(infected_df['long'])\n", + "\n", + "infected_df['northing'], infected_df['easting'] = latlong2osgbgrid_cupy(cupy_lat, cupy_long)\n", + "infected_df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Find Clusters of Infected People" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Use DBSCAN to find clusters of at least 25 infected people where no member is more than 2000m from at least one other cluster member. Create a new column in `infected_df` which contains the cluster to which each infected person belongs." + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dbscan = cuml.DBSCAN(eps = 2000, min_samples = 25)\n", + "infected_df['cluster'] = dbscan.fit_predict(infected_df[['northing', 'easting']])\n", + "infected_df.groupby('cluster')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Find the Centroid of Each Cluster" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Use grouping to find the mean `northing` and `easting` values for each cluster identified above." + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
northingeasting
cluster
-1378094.622647401880.682473
0397661.319575371410.021738
1436475.527827332980.449214
2347062.477357389386.823243
3359668.552556379638.020362
4391630.403390431158.137254
5386471.397432426559.085587
6434970.462486406985.278520
7412772.652344410069.663793
8415808.971615414713.750256
9417322.530166409583.737652
10334208.471668435937.777721
11300568.023792391901.514790
12291539.540205401640.663845
13289855.069902394518.295606
\n", + "
" + ], + "text/plain": [ + " northing easting\n", + "cluster \n", + "-1 378094.622647 401880.682473\n", + " 0 397661.319575 371410.021738\n", + " 1 436475.527827 332980.449214\n", + " 2 347062.477357 389386.823243\n", + " 3 359668.552556 379638.020362\n", + " 4 391630.403390 431158.137254\n", + " 5 386471.397432 426559.085587\n", + " 6 434970.462486 406985.278520\n", + " 7 412772.652344 410069.663793\n", + " 8 415808.971615 414713.750256\n", + " 9 417322.530166 409583.737652\n", + " 10 334208.471668 435937.777721\n", + " 11 300568.023792 391901.514790\n", + " 12 291539.540205 401640.663845\n", + " 13 289855.069902 394518.295606" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "centroids_df = infected_df[['northing', 'easting', 'cluster']].groupby('cluster').mean()\n", + "centroids_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Find the number of people in each cluster by counting the number of appearances of each cluster's label in the column produced by DBSCAN." + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "cluster\n", + "-1 8451\n", + " 0 8638\n", + " 1 68\n", + " 2 403\n", + " 3 25\n", + " 4 66\n", + " 5 43\n", + " 6 27\n", + " 7 39\n", + " 8 92\n", + " 9 21\n", + " 10 64\n", + " 11 68\n", + " 12 72\n", + " 13 71\n", + "dtype: int64" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "infected_df.groupby(['cluster']).size()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Find the Centroid of the Cluster with the Most Members ##" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Use the cluster label for with the most people to filter `centroid_df` and write the answer to `my_assessment/question_1.json`. " + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/lib/python3.10/site-packages/cudf/io/json.py:194: UserWarning: Using CPU via Pandas to write JSON dataset\n", + " warnings.warn(\"Using CPU via Pandas to write JSON dataset\")\n" + ] + } + ], + "source": [ + "centroids_df.loc[0].to_json('my_assessment/question_1.json')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Check Submission ##" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\"northing\":397661.3195752321,\"easting\":371410.0217381102}" + ] + } + ], + "source": [ + "!cat my_assessment/question_1.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Tip**: Your submission file should contain one line of text, similar to: \n", + "\n", + "```\n", + "{'northing':XXX.XX,'easting':XXX.XX}\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Please Restart the Kernel

" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import IPython\n", + "app = IPython.Application.instance()\n", + "app.kernel.do_shutdown(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Header\"" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.15" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/ds/25-1/2/4-03_nearest_facilities.ipynb b/ds/25-1/2/4-03_nearest_facilities.ipynb new file mode 100644 index 0000000..a782601 --- /dev/null +++ b/ds/25-1/2/4-03_nearest_facilities.ipynb @@ -0,0 +1,3718 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Header\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Week 2: Identify Nearest Health Facilities" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "**UPDATE**\n", + "\n", + "Thank you for your analysis. Despite our warning efforts so far, the virus continues to spread rapidly. We want to get infected individuals treatment as quickly as possible, so we need your help to calculate which hospital or clinic is closest to each known infected individual in the population.\n", + "\n", + "\n", + "Your goal for this notebook will be to identify the nearest hospital or clinic for each infected person." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext cudf.pandas\n", + "import pandas as pd\n", + "import cuml\n", + "import cupy as cp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load Population Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Begin by loading the `lat`, `long` and `infected` columns from `'./data/week2.csv'` into a cuDF-accelerated pandas DataFrame called `df`." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latlonginfected
054.522511-1.5718960.0
154.554031-1.5249680.0
254.552483-1.4352030.0
354.537186-1.5662150.0
454.528210-1.5884620.0
............
5847988951.634418-2.9258630.0
5847989051.556969-3.0362900.0
5847989151.588997-2.9219150.0
5847989251.590973-2.9545400.0
5847989351.576717-2.9521420.0
\n", + "

58479894 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " lat long infected\n", + "0 54.522511 -1.571896 0.0\n", + "1 54.554031 -1.524968 0.0\n", + "2 54.552483 -1.435203 0.0\n", + "3 54.537186 -1.566215 0.0\n", + "4 54.528210 -1.588462 0.0\n", + "... ... ... ...\n", + "58479889 51.634418 -2.925863 0.0\n", + "58479890 51.556969 -3.036290 0.0\n", + "58479891 51.588997 -2.921915 0.0\n", + "58479892 51.590973 -2.954540 0.0\n", + "58479893 51.576717 -2.952142 0.0\n", + "\n", + "[58479894 rows x 3 columns]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv('./data/week2.csv', dtype = {\n", + " 'lat': 'float32',\n", + " 'long': 'float32',\n", + " 'infected': 'category',\n", + "}, usecols = ['lat', 'long', 'infected'])\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load Hospital and Clinics Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For this step, your goal is to create an `all_med` cuDF-accelearted pandas DataFrame that contains the latitudes and longitudes of all the hospitals (data found at `'./data/hospitals.csv'`) and clinics (data found at `'./data/clinics.csv'`)." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OrganisationIDOrganisationCodeOrganisationTypeSubTypeSectorOrganisationStatusIsPimsManagedOrganisationNameAddress1Address2...CountyPostcodeLatitudeLongitudeParentODSCodeParentNamePhoneEmailWebsiteFax
017970NDA07HospitalHospitalIndependent SectorVisibleTrueWalton Community Hospital - Virgin Care Servic...<NA>Rodney Road...SurreyKT12 3LD51.37999725-0.406042069NDAVirgin Care Services Ltd01932 414205<NA><NA>01932 253674
117981NDA18HospitalHospitalIndependent SectorVisibleTrueWoking Community Hospital (Virgin Care)<NA>Heathside Road...SurreyGU22 7HS51.31513214-0.556289494NDAVirgin Care Services Ltd01483 715911<NA><NA><NA>
218102NLT02HospitalHospitalNHS SectorVisibleTrueNorth Somerset Community HospitalNorth Somerset Community HospitalOld Street...AvonBS21 6BS51.43719482-2.847192764NLTNorth Somerset Community Partnership Community...01275 872212<NA>http://www.nscphealth.co.uk<NA>
318138NMP01HospitalHospitalIndependent SectorVisibleFalseBridgewater Hospital120 Princess Road<NA>...Greater ManchesterM15 5AT53.4597435-2.245468855NMPBridgewater Hospital (Manchester) Ltd0161 2270000<NA>www.bridgewaterhospital.com<NA>
418142NMV01HospitalHospitalIndependent SectorVisibleTrueKneesworth HouseOld North RoadBassingbourn...<NA>SG8 5JP52.07812119-0.030604055NMVPartnerships In Care Ltd01763 255 700reception_kneesworthhouse@partnershipsincare.c...www.partnershipsincare.co.uk<NA>
..................................................................
122410617466RTH18HospitalUNKNOWNIndependent SectorVisibleFalseUniversity Hospital Of WalesC/O John Radcliffe HospitalHeadley Way...<NA>OX3 9DU51.76387405-1.219792008RTHOxford University Hospitals NHS Foundation Trust<NA><NA><NA><NA>
122510617482RX3KIHospitalUNKNOWNIndependent SectorVisibleFalseFoss Park HospitalHuntington HouseJockey Lane...<NA>YO32 9XW53.98666382-1.051122308RX3Tees, Esk and Wear Valleys NHS Foundation Trust<NA><NA><NA><NA>
122610617567RGT1WHospitalUNKNOWNIndependent SectorVisibleFalseJersey General HospitalThe Parade<NA>...<NA>JE1 3UH<NA><NA>RGTCambridge University Hospitals NHS Foundation ...<NA><NA><NA><NA>
122710617714RAX0AHospitalUNKNOWNIndependent SectorVisibleFalseLondon North West University HospitalsWatford Road<NA>...<NA>HA1 3UJ51.57540894-0.322022736RAXKingston Hospital NHS Foundation Trust<NA><NA><NA><NA>
122810617726RDU5AHospitalUNKNOWNIndependent SectorVisibleFalseJohn Radcliffe HospitalHeadley WayHeadington...<NA>OX3 9DU51.76387405-1.219792008RDUFrimley Health NHS Foundation Trust<NA><NA><NA><NA>
\n", + "

1229 rows × 22 columns

\n", + "
" + ], + "text/plain": [ + " OrganisationID OrganisationCode OrganisationType SubType \\\n", + "0 17970 NDA07 Hospital Hospital \n", + "1 17981 NDA18 Hospital Hospital \n", + "2 18102 NLT02 Hospital Hospital \n", + "3 18138 NMP01 Hospital Hospital \n", + "4 18142 NMV01 Hospital Hospital \n", + "... ... ... ... ... \n", + "1224 10617466 RTH18 Hospital UNKNOWN \n", + "1225 10617482 RX3KI Hospital UNKNOWN \n", + "1226 10617567 RGT1W Hospital UNKNOWN \n", + "1227 10617714 RAX0A Hospital UNKNOWN \n", + "1228 10617726 RDU5A Hospital UNKNOWN \n", + "\n", + " Sector OrganisationStatus IsPimsManaged \\\n", + "0 Independent Sector Visible True \n", + "1 Independent Sector Visible True \n", + "2 NHS Sector Visible True \n", + "3 Independent Sector Visible False \n", + "4 Independent Sector Visible True \n", + "... ... ... ... \n", + "1224 Independent Sector Visible False \n", + "1225 Independent Sector Visible False \n", + "1226 Independent Sector Visible False \n", + "1227 Independent Sector Visible False \n", + "1228 Independent Sector Visible False \n", + "\n", + " OrganisationName \\\n", + "0 Walton Community Hospital - Virgin Care Servic... \n", + "1 Woking Community Hospital (Virgin Care) \n", + "2 North Somerset Community Hospital \n", + "3 Bridgewater Hospital \n", + "4 Kneesworth House \n", + "... ... \n", + "1224 University Hospital Of Wales \n", + "1225 Foss Park Hospital \n", + "1226 Jersey General Hospital \n", + "1227 London North West University Hospitals \n", + "1228 John Radcliffe Hospital \n", + "\n", + " Address1 Address2 ... \\\n", + "0 Rodney Road ... \n", + "1 Heathside Road ... \n", + "2 North Somerset Community Hospital Old Street ... \n", + "3 120 Princess Road ... \n", + "4 Old North Road Bassingbourn ... \n", + "... ... ... ... \n", + "1224 C/O John Radcliffe Hospital Headley Way ... \n", + "1225 Huntington House Jockey Lane ... \n", + "1226 The Parade ... \n", + "1227 Watford Road ... \n", + "1228 Headley Way Headington ... \n", + "\n", + " County Postcode Latitude Longitude ParentODSCode \\\n", + "0 Surrey KT12 3LD 51.37999725 -0.406042069 NDA \n", + "1 Surrey GU22 7HS 51.31513214 -0.556289494 NDA \n", + "2 Avon BS21 6BS 51.43719482 -2.847192764 NLT \n", + "3 Greater Manchester M15 5AT 53.4597435 -2.245468855 NMP \n", + "4 SG8 5JP 52.07812119 -0.030604055 NMV \n", + "... ... ... ... ... ... \n", + "1224 OX3 9DU 51.76387405 -1.219792008 RTH \n", + "1225 YO32 9XW 53.98666382 -1.051122308 RX3 \n", + "1226 JE1 3UH RGT \n", + "1227 HA1 3UJ 51.57540894 -0.322022736 RAX \n", + "1228 OX3 9DU 51.76387405 -1.219792008 RDU \n", + "\n", + " ParentName Phone \\\n", + "0 Virgin Care Services Ltd 01932 414205 \n", + "1 Virgin Care Services Ltd 01483 715911 \n", + "2 North Somerset Community Partnership Community... 01275 872212 \n", + "3 Bridgewater Hospital (Manchester) Ltd 0161 2270000 \n", + "4 Partnerships In Care Ltd 01763 255 700 \n", + "... ... ... \n", + "1224 Oxford University Hospitals NHS Foundation Trust \n", + "1225 Tees, Esk and Wear Valleys NHS Foundation Trust \n", + "1226 Cambridge University Hospitals NHS Foundation ... \n", + "1227 Kingston Hospital NHS Foundation Trust \n", + "1228 Frimley Health NHS Foundation Trust \n", + "\n", + " Email \\\n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 reception_kneesworthhouse@partnershipsincare.c... \n", + "... ... \n", + "1224 \n", + "1225 \n", + "1226 \n", + "1227 \n", + "1228 \n", + "\n", + " Website Fax \n", + "0 01932 253674 \n", + "1 \n", + "2 http://www.nscphealth.co.uk \n", + "3 www.bridgewaterhospital.com \n", + "4 www.partnershipsincare.co.uk \n", + "... ... ... \n", + "1224 \n", + "1225 \n", + "1226 \n", + "1227 \n", + "1228 \n", + "\n", + "[1229 rows x 22 columns]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hospitals_df = pd.read_csv('./data/hospitals.csv')\n", + "hospitals_df" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OrganisationIDOrganisationCodeOrganisationTypeSubTypeOrganisationStatusIsPimsManagedOrganisationNameAddress1Address2Address3CityCountyPostcodeLatitudeLongitudePhoneEmailWebsiteFax
012366F81157ClinicUNKNOWNVisibleTrueFrinton Road Medical Centre<NA>68 Frinton Road, Hollond-on-Sea<NA>Clacton-on-Sea<NA>CO15 5UW51.8042371.186376<NA><NA><NA><NA>
112450F81670ClinicUNKNOWNVisibleTrueEpping Close Surgery<NA>Epping Close<NA>Clacton on Sea<NA>CO15 4UZ51.8152621.15470701255 222668<NA><NA><NA>
212461F81681ClinicUNKNOWNVisibleTrueGreen Elms Medical Centre<NA>32 Crossways<NA>Jaywick, Clacton on Sea<NA>CO15 2NB51.7806211.117907<NA><NA><NA><NA>
317937NAA01ClinicUNKNOWNVisibleFalseSt Chads ClinicSt. Chads Drive<NA><NA>LiverpoolMerseysideL32 8RE53.482368-2.885404<NA><NA><NA><NA>
417938NAA02ClinicUNKNOWNVisibleFalseWhiston Health CentreOld Colliery RoadWhiston<NA>PrescotMerseysideL35 3SX53.415630-2.800874<NA><NA><NA><NA>
............................................................
1907710617742NBG7LClinicUNKNOWNVisibleFalseSunnybank Medical CentreTown GateWyke<NA>Bradford<NA>BD12 9NG53.737923-1.767982<NA><NA><NA><NA>
1907810617743NFH02ClinicUNKNOWNVisibleFalseSomerset Surgical Services At Mendip Vale Medi...Pudding Pie LaneLangford<NA>Bristol<NA>BS40 5EL51.341579-2.784808<NA><NA><NA><NA>
1907910617744NFH03ClinicUNKNOWNVisibleFalseSomerset Surgical Services At Axbridge Medical...Houlgate Way<NA><NA>Axbridge<NA>BS26 2BJ51.286285-2.820388<NA><NA><NA><NA>
1908010617746NEMAMClinicUNKNOWNVisibleFalseLawton House SurgeryBromley Road<NA><NA>Congleton<NA>CW12 1QG53.163048-2.205781<NA><NA><NA><NA>
1908110617747NFH04ClinicUNKNOWNVisibleFalseSomerset Surgical Services At Wedmore Medical ...St. Medard Road<NA><NA>Wedmore<NA>BS28 4AY51.227219-2.816258<NA><NA><NA><NA>
\n", + "

19082 rows × 19 columns

\n", + "
" + ], + "text/plain": [ + " OrganisationID OrganisationCode OrganisationType SubType \\\n", + "0 12366 F81157 Clinic UNKNOWN \n", + "1 12450 F81670 Clinic UNKNOWN \n", + "2 12461 F81681 Clinic UNKNOWN \n", + "3 17937 NAA01 Clinic UNKNOWN \n", + "4 17938 NAA02 Clinic UNKNOWN \n", + "... ... ... ... ... \n", + "19077 10617742 NBG7L Clinic UNKNOWN \n", + "19078 10617743 NFH02 Clinic UNKNOWN \n", + "19079 10617744 NFH03 Clinic UNKNOWN \n", + "19080 10617746 NEMAM Clinic UNKNOWN \n", + "19081 10617747 NFH04 Clinic UNKNOWN \n", + "\n", + " OrganisationStatus IsPimsManaged \\\n", + "0 Visible True \n", + "1 Visible True \n", + "2 Visible True \n", + "3 Visible False \n", + "4 Visible False \n", + "... ... ... \n", + "19077 Visible False \n", + "19078 Visible False \n", + "19079 Visible False \n", + "19080 Visible False \n", + "19081 Visible False \n", + "\n", + " OrganisationName Address1 \\\n", + "0 Frinton Road Medical Centre \n", + "1 Epping Close Surgery \n", + "2 Green Elms Medical Centre \n", + "3 St Chads Clinic St. Chads Drive \n", + "4 Whiston Health Centre Old Colliery Road \n", + "... ... ... \n", + "19077 Sunnybank Medical Centre Town Gate \n", + "19078 Somerset Surgical Services At Mendip Vale Medi... Pudding Pie Lane \n", + "19079 Somerset Surgical Services At Axbridge Medical... Houlgate Way \n", + "19080 Lawton House Surgery Bromley Road \n", + "19081 Somerset Surgical Services At Wedmore Medical ... St. Medard Road \n", + "\n", + " Address2 Address3 City \\\n", + "0 68 Frinton Road, Hollond-on-Sea Clacton-on-Sea \n", + "1 Epping Close Clacton on Sea \n", + "2 32 Crossways Jaywick, Clacton on Sea \n", + "3 Liverpool \n", + "4 Whiston Prescot \n", + "... ... ... ... \n", + "19077 Wyke Bradford \n", + "19078 Langford Bristol \n", + "19079 Axbridge \n", + "19080 Congleton \n", + "19081 Wedmore \n", + "\n", + " County Postcode Latitude Longitude Phone Email Website \\\n", + "0 CO15 5UW 51.804237 1.186376 \n", + "1 CO15 4UZ 51.815262 1.154707 01255 222668 \n", + "2 CO15 2NB 51.780621 1.117907 \n", + "3 Merseyside L32 8RE 53.482368 -2.885404 \n", + "4 Merseyside L35 3SX 53.415630 -2.800874 \n", + "... ... ... ... ... ... ... ... \n", + "19077 BD12 9NG 53.737923 -1.767982 \n", + "19078 BS40 5EL 51.341579 -2.784808 \n", + "19079 BS26 2BJ 51.286285 -2.820388 \n", + "19080 CW12 1QG 53.163048 -2.205781 \n", + "19081 BS28 4AY 51.227219 -2.816258 \n", + "\n", + " Fax \n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 \n", + "... ... \n", + "19077 \n", + "19078 \n", + "19079 \n", + "19080 \n", + "19081 \n", + "\n", + "[19082 rows x 19 columns]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clinics_df = pd.read_csv('./data/clinics.csv')\n", + "clinics_df" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OrganisationIDOrganisationCodeOrganisationTypeSubTypeSectorOrganisationStatusIsPimsManagedOrganisationNameAddress1Address2...CountyPostcodeLatitudeLongitudeParentODSCodeParentNamePhoneEmailWebsiteFax
017970NDA07HospitalHospitalIndependent SectorVisibleTrueWalton Community Hospital - Virgin Care Servic...<NA>Rodney Road...SurreyKT12 3LD51.379997-0.406042NDAVirgin Care Services Ltd01932 414205<NA><NA>01932 253674
117981NDA18HospitalHospitalIndependent SectorVisibleTrueWoking Community Hospital (Virgin Care)<NA>Heathside Road...SurreyGU22 7HS51.315132-0.556289NDAVirgin Care Services Ltd01483 715911<NA><NA><NA>
218102NLT02HospitalHospitalNHS SectorVisibleTrueNorth Somerset Community HospitalNorth Somerset Community HospitalOld Street...AvonBS21 6BS51.437195-2.847193NLTNorth Somerset Community Partnership Community...01275 872212<NA>http://www.nscphealth.co.uk<NA>
318138NMP01HospitalHospitalIndependent SectorVisibleFalseBridgewater Hospital120 Princess Road<NA>...Greater ManchesterM15 5AT53.459743-2.245469NMPBridgewater Hospital (Manchester) Ltd0161 2270000<NA>www.bridgewaterhospital.com<NA>
418142NMV01HospitalHospitalIndependent SectorVisibleTrueKneesworth HouseOld North RoadBassingbourn...<NA>SG8 5JP52.078121-0.030604NMVPartnerships In Care Ltd01763 255 700reception_kneesworthhouse@partnershipsincare.c...www.partnershipsincare.co.uk<NA>
..................................................................
1907710617742NBG7LClinicUNKNOWN<NA>VisibleFalseSunnybank Medical CentreTown GateWyke...<NA>BD12 9NG53.737923-1.767982<NA><NA><NA><NA><NA><NA>
1907810617743NFH02ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Mendip Vale Medi...Pudding Pie LaneLangford...<NA>BS40 5EL51.341579-2.784808<NA><NA><NA><NA><NA><NA>
1907910617744NFH03ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Axbridge Medical...Houlgate Way<NA>...<NA>BS26 2BJ51.286285-2.820388<NA><NA><NA><NA><NA><NA>
1908010617746NEMAMClinicUNKNOWN<NA>VisibleFalseLawton House SurgeryBromley Road<NA>...<NA>CW12 1QG53.163048-2.205781<NA><NA><NA><NA><NA><NA>
1908110617747NFH04ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Wedmore Medical ...St. Medard Road<NA>...<NA>BS28 4AY51.227219-2.816258<NA><NA><NA><NA><NA><NA>
\n", + "

20311 rows × 22 columns

\n", + "
" + ], + "text/plain": [ + " OrganisationID OrganisationCode OrganisationType SubType \\\n", + "0 17970 NDA07 Hospital Hospital \n", + "1 17981 NDA18 Hospital Hospital \n", + "2 18102 NLT02 Hospital Hospital \n", + "3 18138 NMP01 Hospital Hospital \n", + "4 18142 NMV01 Hospital Hospital \n", + "... ... ... ... ... \n", + "19077 10617742 NBG7L Clinic UNKNOWN \n", + "19078 10617743 NFH02 Clinic UNKNOWN \n", + "19079 10617744 NFH03 Clinic UNKNOWN \n", + "19080 10617746 NEMAM Clinic UNKNOWN \n", + "19081 10617747 NFH04 Clinic UNKNOWN \n", + "\n", + " Sector OrganisationStatus IsPimsManaged \\\n", + "0 Independent Sector Visible True \n", + "1 Independent Sector Visible True \n", + "2 NHS Sector Visible True \n", + "3 Independent Sector Visible False \n", + "4 Independent Sector Visible True \n", + "... ... ... ... \n", + "19077 Visible False \n", + "19078 Visible False \n", + "19079 Visible False \n", + "19080 Visible False \n", + "19081 Visible False \n", + "\n", + " OrganisationName \\\n", + "0 Walton Community Hospital - Virgin Care Servic... \n", + "1 Woking Community Hospital (Virgin Care) \n", + "2 North Somerset Community Hospital \n", + "3 Bridgewater Hospital \n", + "4 Kneesworth House \n", + "... ... \n", + "19077 Sunnybank Medical Centre \n", + "19078 Somerset Surgical Services At Mendip Vale Medi... \n", + "19079 Somerset Surgical Services At Axbridge Medical... \n", + "19080 Lawton House Surgery \n", + "19081 Somerset Surgical Services At Wedmore Medical ... \n", + "\n", + " Address1 Address2 ... \\\n", + "0 Rodney Road ... \n", + "1 Heathside Road ... \n", + "2 North Somerset Community Hospital Old Street ... \n", + "3 120 Princess Road ... \n", + "4 Old North Road Bassingbourn ... \n", + "... ... ... ... \n", + "19077 Town Gate Wyke ... \n", + "19078 Pudding Pie Lane Langford ... \n", + "19079 Houlgate Way ... \n", + "19080 Bromley Road ... \n", + "19081 St. Medard Road ... \n", + "\n", + " County Postcode Latitude Longitude ParentODSCode \\\n", + "0 Surrey KT12 3LD 51.379997 -0.406042 NDA \n", + "1 Surrey GU22 7HS 51.315132 -0.556289 NDA \n", + "2 Avon BS21 6BS 51.437195 -2.847193 NLT \n", + "3 Greater Manchester M15 5AT 53.459743 -2.245469 NMP \n", + "4 SG8 5JP 52.078121 -0.030604 NMV \n", + "... ... ... ... ... ... \n", + "19077 BD12 9NG 53.737923 -1.767982 \n", + "19078 BS40 5EL 51.341579 -2.784808 \n", + "19079 BS26 2BJ 51.286285 -2.820388 \n", + "19080 CW12 1QG 53.163048 -2.205781 \n", + "19081 BS28 4AY 51.227219 -2.816258 \n", + "\n", + " ParentName Phone \\\n", + "0 Virgin Care Services Ltd 01932 414205 \n", + "1 Virgin Care Services Ltd 01483 715911 \n", + "2 North Somerset Community Partnership Community... 01275 872212 \n", + "3 Bridgewater Hospital (Manchester) Ltd 0161 2270000 \n", + "4 Partnerships In Care Ltd 01763 255 700 \n", + "... ... ... \n", + "19077 \n", + "19078 \n", + "19079 \n", + "19080 \n", + "19081 \n", + "\n", + " Email \\\n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 reception_kneesworthhouse@partnershipsincare.c... \n", + "... ... \n", + "19077 \n", + "19078 \n", + "19079 \n", + "19080 \n", + "19081 \n", + "\n", + " Website Fax \n", + "0 01932 253674 \n", + "1 \n", + "2 http://www.nscphealth.co.uk \n", + "3 www.bridgewaterhospital.com \n", + "4 www.partnershipsincare.co.uk \n", + "... ... ... \n", + "19077 \n", + "19078 \n", + "19079 \n", + "19080 \n", + "19081 \n", + "\n", + "[20311 rows x 22 columns]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_med = pd.concat([hospitals_df, clinics_df])\n", + "all_med" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since we will be using the coordinates of those facilities, keep only those rows that are non-null in both `Latitude` and `Longitude`.\n", + "\n", + "**Tip**: Reset the index of `all_med` with `.reset_index(drop=True)`. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OrganisationIDOrganisationCodeOrganisationTypeSubTypeSectorOrganisationStatusIsPimsManagedOrganisationNameAddress1Address2...CountyPostcodeLatitudeLongitudeParentODSCodeParentNamePhoneEmailWebsiteFax
017970NDA07HospitalHospitalIndependent SectorVisibleTrueWalton Community Hospital - Virgin Care Servic...<NA>Rodney Road...SurreyKT12 3LD51.379997-0.406042NDAVirgin Care Services Ltd01932 414205<NA><NA>01932 253674
117981NDA18HospitalHospitalIndependent SectorVisibleTrueWoking Community Hospital (Virgin Care)<NA>Heathside Road...SurreyGU22 7HS51.315132-0.556289NDAVirgin Care Services Ltd01483 715911<NA><NA><NA>
218102NLT02HospitalHospitalNHS SectorVisibleTrueNorth Somerset Community HospitalNorth Somerset Community HospitalOld Street...AvonBS21 6BS51.437195-2.847193NLTNorth Somerset Community Partnership Community...01275 872212<NA>http://www.nscphealth.co.uk<NA>
318138NMP01HospitalHospitalIndependent SectorVisibleFalseBridgewater Hospital120 Princess Road<NA>...Greater ManchesterM15 5AT53.459743-2.245469NMPBridgewater Hospital (Manchester) Ltd0161 2270000<NA>www.bridgewaterhospital.com<NA>
418142NMV01HospitalHospitalIndependent SectorVisibleTrueKneesworth HouseOld North RoadBassingbourn...<NA>SG8 5JP52.078121-0.030604NMVPartnerships In Care Ltd01763 255 700reception_kneesworthhouse@partnershipsincare.c...www.partnershipsincare.co.uk<NA>
..................................................................
2029610617742NBG7LClinicUNKNOWN<NA>VisibleFalseSunnybank Medical CentreTown GateWyke...<NA>BD12 9NG53.737923-1.767982<NA><NA><NA><NA><NA><NA>
2029710617743NFH02ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Mendip Vale Medi...Pudding Pie LaneLangford...<NA>BS40 5EL51.341579-2.784808<NA><NA><NA><NA><NA><NA>
2029810617744NFH03ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Axbridge Medical...Houlgate Way<NA>...<NA>BS26 2BJ51.286285-2.820388<NA><NA><NA><NA><NA><NA>
2029910617746NEMAMClinicUNKNOWN<NA>VisibleFalseLawton House SurgeryBromley Road<NA>...<NA>CW12 1QG53.163048-2.205781<NA><NA><NA><NA><NA><NA>
2030010617747NFH04ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Wedmore Medical ...St. Medard Road<NA>...<NA>BS28 4AY51.227219-2.816258<NA><NA><NA><NA><NA><NA>
\n", + "

20301 rows × 22 columns

\n", + "
" + ], + "text/plain": [ + " OrganisationID OrganisationCode OrganisationType SubType \\\n", + "0 17970 NDA07 Hospital Hospital \n", + "1 17981 NDA18 Hospital Hospital \n", + "2 18102 NLT02 Hospital Hospital \n", + "3 18138 NMP01 Hospital Hospital \n", + "4 18142 NMV01 Hospital Hospital \n", + "... ... ... ... ... \n", + "20296 10617742 NBG7L Clinic UNKNOWN \n", + "20297 10617743 NFH02 Clinic UNKNOWN \n", + "20298 10617744 NFH03 Clinic UNKNOWN \n", + "20299 10617746 NEMAM Clinic UNKNOWN \n", + "20300 10617747 NFH04 Clinic UNKNOWN \n", + "\n", + " Sector OrganisationStatus IsPimsManaged \\\n", + "0 Independent Sector Visible True \n", + "1 Independent Sector Visible True \n", + "2 NHS Sector Visible True \n", + "3 Independent Sector Visible False \n", + "4 Independent Sector Visible True \n", + "... ... ... ... \n", + "20296 Visible False \n", + "20297 Visible False \n", + "20298 Visible False \n", + "20299 Visible False \n", + "20300 Visible False \n", + "\n", + " OrganisationName \\\n", + "0 Walton Community Hospital - Virgin Care Servic... \n", + "1 Woking Community Hospital (Virgin Care) \n", + "2 North Somerset Community Hospital \n", + "3 Bridgewater Hospital \n", + "4 Kneesworth House \n", + "... ... \n", + "20296 Sunnybank Medical Centre \n", + "20297 Somerset Surgical Services At Mendip Vale Medi... \n", + "20298 Somerset Surgical Services At Axbridge Medical... \n", + "20299 Lawton House Surgery \n", + "20300 Somerset Surgical Services At Wedmore Medical ... \n", + "\n", + " Address1 Address2 ... \\\n", + "0 Rodney Road ... \n", + "1 Heathside Road ... \n", + "2 North Somerset Community Hospital Old Street ... \n", + "3 120 Princess Road ... \n", + "4 Old North Road Bassingbourn ... \n", + "... ... ... ... \n", + "20296 Town Gate Wyke ... \n", + "20297 Pudding Pie Lane Langford ... \n", + "20298 Houlgate Way ... \n", + "20299 Bromley Road ... \n", + "20300 St. Medard Road ... \n", + "\n", + " County Postcode Latitude Longitude ParentODSCode \\\n", + "0 Surrey KT12 3LD 51.379997 -0.406042 NDA \n", + "1 Surrey GU22 7HS 51.315132 -0.556289 NDA \n", + "2 Avon BS21 6BS 51.437195 -2.847193 NLT \n", + "3 Greater Manchester M15 5AT 53.459743 -2.245469 NMP \n", + "4 SG8 5JP 52.078121 -0.030604 NMV \n", + "... ... ... ... ... ... \n", + "20296 BD12 9NG 53.737923 -1.767982 \n", + "20297 BS40 5EL 51.341579 -2.784808 \n", + "20298 BS26 2BJ 51.286285 -2.820388 \n", + "20299 CW12 1QG 53.163048 -2.205781 \n", + "20300 BS28 4AY 51.227219 -2.816258 \n", + "\n", + " ParentName Phone \\\n", + "0 Virgin Care Services Ltd 01932 414205 \n", + "1 Virgin Care Services Ltd 01483 715911 \n", + "2 North Somerset Community Partnership Community... 01275 872212 \n", + "3 Bridgewater Hospital (Manchester) Ltd 0161 2270000 \n", + "4 Partnerships In Care Ltd 01763 255 700 \n", + "... ... ... \n", + "20296 \n", + "20297 \n", + "20298 \n", + "20299 \n", + "20300 \n", + "\n", + " Email \\\n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 reception_kneesworthhouse@partnershipsincare.c... \n", + "... ... \n", + "20296 \n", + "20297 \n", + "20298 \n", + "20299 \n", + "20300 \n", + "\n", + " Website Fax \n", + "0 01932 253674 \n", + "1 \n", + "2 http://www.nscphealth.co.uk \n", + "3 www.bridgewaterhospital.com \n", + "4 www.partnershipsincare.co.uk \n", + "... ... ... \n", + "20296 \n", + "20297 \n", + "20298 \n", + "20299 \n", + "20300 \n", + "\n", + "[20301 rows x 22 columns]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_med = all_med.dropna(subset=['Latitude', 'Longitude'])\n", + "\n", + "all_med = all_med.reset_index(drop=True)\n", + "\n", + "all_med " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Make Grid Coordinates for Medical Facilities" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Provided for you in the next cell (which you can expand by clicking on the \"...\", and contract again after executing by clicking on the blue left border of the cell) is the lat/long to grid coordinates converter you have used earlier in the workshop. Use this converter to create grid coordinate values stored in `northing` and `easting` columns of the `all_med` DataFrame you created in the last step." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, + "outputs": [], + "source": [ + "# https://www.ordnancesurvey.co.uk/docs/support/guide-coordinate-systems-great-britain.pdf\n", + "\n", + "def latlong2osgbgrid_cupy(lat, long, input_degrees=True):\n", + " '''\n", + " Converts latitude and longitude (ellipsoidal) coordinates into northing and easting (grid) coordinates, using a Transverse Mercator projection.\n", + " \n", + " Inputs:\n", + " lat: latitude coordinate (N)\n", + " long: longitude coordinate (E)\n", + " input_degrees: if True (default), interprets the coordinates as degrees; otherwise, interprets coordinates as radians\n", + " \n", + " Output:\n", + " (northing, easting)\n", + " '''\n", + " \n", + " if input_degrees:\n", + " lat = lat * cp.pi/180\n", + " long = long * cp.pi/180\n", + "\n", + " a = 6377563.396\n", + " b = 6356256.909\n", + " e2 = (a**2 - b**2) / a**2\n", + "\n", + " N0 = -100000 # northing of true origin\n", + " E0 = 400000 # easting of true origin\n", + " F0 = .9996012717 # scale factor on central meridian\n", + " phi0 = 49 * cp.pi / 180 # latitude of true origin\n", + " lambda0 = -2 * cp.pi / 180 # longitude of true origin and central meridian\n", + " \n", + " sinlat = cp.sin(lat)\n", + " coslat = cp.cos(lat)\n", + " tanlat = cp.tan(lat)\n", + " \n", + " latdiff = lat-phi0\n", + " longdiff = long-lambda0\n", + "\n", + " n = (a-b) / (a+b)\n", + " nu = a * F0 * (1 - e2 * sinlat ** 2) ** -.5\n", + " rho = a * F0 * (1 - e2) * (1 - e2 * sinlat ** 2) ** -1.5\n", + " eta2 = nu / rho - 1\n", + " M = b * F0 * ((1 + n + 5/4 * (n**2 + n**3)) * latdiff - \n", + " (3*(n+n**2) + 21/8 * n**3) * cp.sin(latdiff) * cp.cos(lat+phi0) +\n", + " 15/8 * (n**2 + n**3) * cp.sin(2*(latdiff)) * cp.cos(2*(lat+phi0)) - \n", + " 35/24 * n**3 * cp.sin(3*(latdiff)) * cp.cos(3*(lat+phi0)))\n", + " I = M + N0\n", + " II = nu/2 * sinlat * coslat\n", + " III = nu/24 * sinlat * coslat ** 3 * (5 - tanlat ** 2 + 9 * eta2)\n", + " IIIA = nu/720 * sinlat * coslat ** 5 * (61-58 * tanlat**2 + tanlat**4)\n", + " IV = nu * coslat\n", + " V = nu / 6 * coslat**3 * (nu/rho - cp.tan(lat)**2)\n", + " VI = nu / 120 * coslat ** 5 * (5 - 18 * tanlat**2 + tanlat**4 + 14 * eta2 - 58 * tanlat**2 * eta2)\n", + "\n", + " northing = I + II * longdiff**2 + III * longdiff**4 + IIIA * longdiff**6\n", + " easting = E0 + IV * longdiff + V * longdiff**3 + VI * longdiff**5\n", + "\n", + " return(northing, easting)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OrganisationIDOrganisationCodeOrganisationTypeSubTypeSectorOrganisationStatusIsPimsManagedOrganisationNameAddress1Address2...LatitudeLongitudeParentODSCodeParentNamePhoneEmailWebsiteFaxnorthingeasting
017970NDA07HospitalHospitalIndependent SectorVisibleTrueWalton Community Hospital - Virgin Care Servic...<NA>Rodney Road...51.379997-0.406042NDAVirgin Care Services Ltd01932 414205<NA><NA>01932 253674165810.473974510917.517174
117981NDA18HospitalHospitalIndependent SectorVisibleTrueWoking Community Hospital (Virgin Care)<NA>Heathside Road...51.315132-0.556289NDAVirgin Care Services Ltd01483 715911<NA><NA><NA>158381.343420500604.836652
218102NLT02HospitalHospitalNHS SectorVisibleTrueNorth Somerset Community HospitalNorth Somerset Community HospitalOld Street...51.437195-2.847193NLTNorth Somerset Community Partnership Community...01275 872212<NA>http://www.nscphealth.co.uk<NA>171305.775859341119.365090
318138NMP01HospitalHospitalIndependent SectorVisibleFalseBridgewater Hospital120 Princess Road<NA>...53.459743-2.245469NMPBridgewater Hospital (Manchester) Ltd0161 2270000<NA>www.bridgewaterhospital.com<NA>395944.561405383703.600293
418142NMV01HospitalHospitalIndependent SectorVisibleTrueKneesworth HouseOld North RoadBassingbourn...52.078121-0.030604NMVPartnerships In Care Ltd01763 255 700reception_kneesworthhouse@partnershipsincare.c...www.partnershipsincare.co.uk<NA>244071.710013534945.182860
..................................................................
2029610617742NBG7LClinicUNKNOWN<NA>VisibleFalseSunnybank Medical CentreTown GateWyke...53.737923-1.767982<NA><NA><NA><NA><NA><NA>426887.040596415302.519662
2029710617743NFH02ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Mendip Vale Medi...Pudding Pie LaneLangford...51.341579-2.784808<NA><NA><NA><NA><NA><NA>160625.127012345341.262026
2029810617744NFH03ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Axbridge Medical...Houlgate Way<NA>...51.286285-2.820388<NA><NA><NA><NA><NA><NA>154503.665383342794.591249
2029910617746NEMAMClinicUNKNOWN<NA>VisibleFalseLawton House SurgeryBromley Road<NA>...53.163048-2.205781<NA><NA><NA><NA><NA><NA>362932.494686386243.408863
2030010617747NFH04ClinicUNKNOWN<NA>VisibleFalseSomerset Surgical Services At Wedmore Medical ...St. Medard Road<NA>...51.227219-2.816258<NA><NA><NA><NA><NA><NA>147932.429756343009.593212
\n", + "

20301 rows × 24 columns

\n", + "
" + ], + "text/plain": [ + " OrganisationID OrganisationCode OrganisationType SubType \\\n", + "0 17970 NDA07 Hospital Hospital \n", + "1 17981 NDA18 Hospital Hospital \n", + "2 18102 NLT02 Hospital Hospital \n", + "3 18138 NMP01 Hospital Hospital \n", + "4 18142 NMV01 Hospital Hospital \n", + "... ... ... ... ... \n", + "20296 10617742 NBG7L Clinic UNKNOWN \n", + "20297 10617743 NFH02 Clinic UNKNOWN \n", + "20298 10617744 NFH03 Clinic UNKNOWN \n", + "20299 10617746 NEMAM Clinic UNKNOWN \n", + "20300 10617747 NFH04 Clinic UNKNOWN \n", + "\n", + " Sector OrganisationStatus IsPimsManaged \\\n", + "0 Independent Sector Visible True \n", + "1 Independent Sector Visible True \n", + "2 NHS Sector Visible True \n", + "3 Independent Sector Visible False \n", + "4 Independent Sector Visible True \n", + "... ... ... ... \n", + "20296 Visible False \n", + "20297 Visible False \n", + "20298 Visible False \n", + "20299 Visible False \n", + "20300 Visible False \n", + "\n", + " OrganisationName \\\n", + "0 Walton Community Hospital - Virgin Care Servic... \n", + "1 Woking Community Hospital (Virgin Care) \n", + "2 North Somerset Community Hospital \n", + "3 Bridgewater Hospital \n", + "4 Kneesworth House \n", + "... ... \n", + "20296 Sunnybank Medical Centre \n", + "20297 Somerset Surgical Services At Mendip Vale Medi... \n", + "20298 Somerset Surgical Services At Axbridge Medical... \n", + "20299 Lawton House Surgery \n", + "20300 Somerset Surgical Services At Wedmore Medical ... \n", + "\n", + " Address1 Address2 ... Latitude \\\n", + "0 Rodney Road ... 51.379997 \n", + "1 Heathside Road ... 51.315132 \n", + "2 North Somerset Community Hospital Old Street ... 51.437195 \n", + "3 120 Princess Road ... 53.459743 \n", + "4 Old North Road Bassingbourn ... 52.078121 \n", + "... ... ... ... ... \n", + "20296 Town Gate Wyke ... 53.737923 \n", + "20297 Pudding Pie Lane Langford ... 51.341579 \n", + "20298 Houlgate Way ... 51.286285 \n", + "20299 Bromley Road ... 53.163048 \n", + "20300 St. Medard Road ... 51.227219 \n", + "\n", + " Longitude ParentODSCode \\\n", + "0 -0.406042 NDA \n", + "1 -0.556289 NDA \n", + "2 -2.847193 NLT \n", + "3 -2.245469 NMP \n", + "4 -0.030604 NMV \n", + "... ... ... \n", + "20296 -1.767982 \n", + "20297 -2.784808 \n", + "20298 -2.820388 \n", + "20299 -2.205781 \n", + "20300 -2.816258 \n", + "\n", + " ParentName Phone \\\n", + "0 Virgin Care Services Ltd 01932 414205 \n", + "1 Virgin Care Services Ltd 01483 715911 \n", + "2 North Somerset Community Partnership Community... 01275 872212 \n", + "3 Bridgewater Hospital (Manchester) Ltd 0161 2270000 \n", + "4 Partnerships In Care Ltd 01763 255 700 \n", + "... ... ... \n", + "20296 \n", + "20297 \n", + "20298 \n", + "20299 \n", + "20300 \n", + "\n", + " Email \\\n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 reception_kneesworthhouse@partnershipsincare.c... \n", + "... ... \n", + "20296 \n", + "20297 \n", + "20298 \n", + "20299 \n", + "20300 \n", + "\n", + " Website Fax northing \\\n", + "0 01932 253674 165810.473974 \n", + "1 158381.343420 \n", + "2 http://www.nscphealth.co.uk 171305.775859 \n", + "3 www.bridgewaterhospital.com 395944.561405 \n", + "4 www.partnershipsincare.co.uk 244071.710013 \n", + "... ... ... ... \n", + "20296 426887.040596 \n", + "20297 160625.127012 \n", + "20298 154503.665383 \n", + "20299 362932.494686 \n", + "20300 147932.429756 \n", + "\n", + " easting \n", + "0 510917.517174 \n", + "1 500604.836652 \n", + "2 341119.365090 \n", + "3 383703.600293 \n", + "4 534945.182860 \n", + "... ... \n", + "20296 415302.519662 \n", + "20297 345341.262026 \n", + "20298 342794.591249 \n", + "20299 386243.408863 \n", + "20300 343009.593212 \n", + "\n", + "[20301 rows x 24 columns]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cupy_lat = cp.asarray(all_med['Latitude'])\n", + "cupy_long = cp.asarray(all_med['Longitude'])\n", + "\n", + "all_med['northing'], all_med['easting'] = latlong2osgbgrid_cupy(cupy_lat, cupy_long)\n", + "all_med" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Find Closest Hospital or Clinic for Infected" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Fit `cuml.NearestNeighbors` with `all_med`'s `northing` and `easting` values, using the named argument `n_neighbors` set to `1`, and save the model as `knn`." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
NearestNeighbors()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "NearestNeighbors()" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "knn = cuml.NearestNeighbors(n_neighbors = 1)\n", + "knn.fit(all_med[['northing', 'easting']])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Save every infected member in `df` into a new dataframe called `infected_df`.\n", + "\n", + "**Tip**: Reset the index of `infected_df` with `.reset_index(drop=True)`. " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latlonginfected
053.715828-2.4300791.0
153.664883-2.4256731.0
253.696766-2.4889401.0
353.696968-2.4888961.0
453.727806-2.3929591.0
............
7087551.662720-2.9268501.0
7087651.599346-2.9591751.0
7087751.543823-2.8229841.0
7087851.562538-2.8794911.0
7087951.628746-2.8371511.0
\n", + "

70880 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " lat long infected\n", + "0 53.715828 -2.430079 1.0\n", + "1 53.664883 -2.425673 1.0\n", + "2 53.696766 -2.488940 1.0\n", + "3 53.696968 -2.488896 1.0\n", + "4 53.727806 -2.392959 1.0\n", + "... ... ... ...\n", + "70875 51.662720 -2.926850 1.0\n", + "70876 51.599346 -2.959175 1.0\n", + "70877 51.543823 -2.822984 1.0\n", + "70878 51.562538 -2.879491 1.0\n", + "70879 51.628746 -2.837151 1.0\n", + "\n", + "[70880 rows x 3 columns]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "infected_filter = df['infected']==1.0\n", + "infected_df = df[infected_filter]\n", + "infected_df.reset_index(drop=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create `northing` and `easting` values for `infected_df`." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latlonginfectednorthingeasting
134658653.715828-2.4300791.0424490.112088371619.667512
135093253.664883-2.4256731.0418820.846058371876.457712
135208553.696766-2.4889401.0422394.870545367720.997655
135279953.696968-2.4888961.0422416.913323367723.982001
135752953.727806-2.3929591.0425808.233176374076.541266
..................
5845918951.662720-2.9268501.0196451.737635335900.977614
5845955151.599346-2.9591751.0189433.231857333572.971111
5846193551.543823-2.8229841.0183144.006910342935.102589
5846408251.562538-2.8794911.0185270.694643339042.064721
5846420951.628746-2.8371511.0192598.453599342060.982494
\n", + "

70880 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " lat long infected northing easting\n", + "1346586 53.715828 -2.430079 1.0 424490.112088 371619.667512\n", + "1350932 53.664883 -2.425673 1.0 418820.846058 371876.457712\n", + "1352085 53.696766 -2.488940 1.0 422394.870545 367720.997655\n", + "1352799 53.696968 -2.488896 1.0 422416.913323 367723.982001\n", + "1357529 53.727806 -2.392959 1.0 425808.233176 374076.541266\n", + "... ... ... ... ... ...\n", + "58459189 51.662720 -2.926850 1.0 196451.737635 335900.977614\n", + "58459551 51.599346 -2.959175 1.0 189433.231857 333572.971111\n", + "58461935 51.543823 -2.822984 1.0 183144.006910 342935.102589\n", + "58464082 51.562538 -2.879491 1.0 185270.694643 339042.064721\n", + "58464209 51.628746 -2.837151 1.0 192598.453599 342060.982494\n", + "\n", + "[70880 rows x 5 columns]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cupy_infected_lat = cp.asarray(infected_df['lat'])\n", + "cupy_infected_long = cp.asarray(infected_df['long'])\n", + "\n", + "infected_df['northing'], infected_df['easting'] = latlong2osgbgrid_cupy(cupy_infected_lat, cupy_infected_long)\n", + "infected_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Use `knn.kneighbors` with `n_neighbors=1` on `infected_df`'s `northing` and `easting` values. Save the return values in `distances` and `indices`." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latlonginfectednorthingeastingdistanceclosest_clinic_hospital
134658653.715828-2.4300791.0424490.112088371619.6675122562.54882818316
135093253.664883-2.4256731.0418820.846058371876.4577122988.74682612816
135208553.696766-2.4889401.0422394.870545367720.9976551162.7340097785
135279953.696968-2.4888961.0422416.913323367723.9820011162.2948007785
135752953.727806-2.3929591.0425808.233176374076.5412661455.0203864962
........................
5845918951.662720-2.9268501.0196451.737635335900.9776148617.89062510015
5845955151.599346-2.9591751.0189433.231857333572.9711111306.79284710015
5846193551.543823-2.8229841.0183144.006910342935.1025897633.3242193814
5846408251.562538-2.8794911.0185270.694643339042.0647217071.18750010015
5846420951.628746-2.8371511.0192598.453599342060.98249410222.50293010015
\n", + "

70880 rows × 7 columns

\n", + "
" + ], + "text/plain": [ + " lat long infected northing easting \\\n", + "1346586 53.715828 -2.430079 1.0 424490.112088 371619.667512 \n", + "1350932 53.664883 -2.425673 1.0 418820.846058 371876.457712 \n", + "1352085 53.696766 -2.488940 1.0 422394.870545 367720.997655 \n", + "1352799 53.696968 -2.488896 1.0 422416.913323 367723.982001 \n", + "1357529 53.727806 -2.392959 1.0 425808.233176 374076.541266 \n", + "... ... ... ... ... ... \n", + "58459189 51.662720 -2.926850 1.0 196451.737635 335900.977614 \n", + "58459551 51.599346 -2.959175 1.0 189433.231857 333572.971111 \n", + "58461935 51.543823 -2.822984 1.0 183144.006910 342935.102589 \n", + "58464082 51.562538 -2.879491 1.0 185270.694643 339042.064721 \n", + "58464209 51.628746 -2.837151 1.0 192598.453599 342060.982494 \n", + "\n", + " distance closest_clinic_hospital \n", + "1346586 2562.548828 18316 \n", + "1350932 2988.746826 12816 \n", + "1352085 1162.734009 7785 \n", + "1352799 1162.294800 7785 \n", + "1357529 1455.020386 4962 \n", + "... ... ... \n", + "58459189 8617.890625 10015 \n", + "58459551 1306.792847 10015 \n", + "58461935 7633.324219 3814 \n", + "58464082 7071.187500 10015 \n", + "58464209 10222.502930 10015 \n", + "\n", + "[70880 rows x 7 columns]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "distances, indices = knn.kneighbors(infected_df[['northing', 'easting']])\n", + "infected_df['distance']=distances\n", + "infected_df['closest_clinic_hospital']=indices\n", + "infected_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### View Closest Clinic/Hospital ###" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`indices`, returned from your use of `knn.kneighbors` immediately above, should map person indices to their closest clinic/hospital indices:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here you can print an infected individual's coordinates from `infected_df`:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "lat 53.715828\n", + "long -2.430079\n", + "infected 1.0\n", + "northing 424490.112088\n", + "easting 371619.667512\n", + "distance 2562.548828\n", + "closest_clinic_hospital 18316\n", + "Name: 1346586, dtype: object" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "infected_df.iloc[0] # get the coords of an infected individual (in this case, individual 0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You should be able to used the mapped index for the nearest facility to see that indeed the nearest facility is at a nearby coordinate:" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "OrganisationID 9445963\n", + "OrganisationCode NPR0F\n", + "OrganisationType Clinic\n", + "SubType UNKNOWN\n", + "Sector None\n", + "OrganisationStatus Visible\n", + "IsPimsManaged False\n", + "OrganisationName Community Dermatology Service - About Health\n", + "Address1 The Innovation Centre\n", + "Address2 1 Evolution Park\n", + "Address3 Haslingden Road\n", + "City Blackburn\n", + "County Lancashire\n", + "Postcode BB1 2FD\n", + "Latitude 53.733227\n", + "Longitude -2.455536\n", + "ParentODSCode None\n", + "ParentName None\n", + "Phone None\n", + "Email None\n", + "Website None\n", + "Fax None\n", + "northing 426435.969251\n", + "easting 369952.220236\n", + "Name: 18316, dtype: object" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_med.iloc[18316] # printing the entry for facility 1234 (replace with the index identified as closest to the individual)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## New Patients ##" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Use the `knn` model to find the closest clinic/hospital for the below new patients. " + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namenorthingeastingdistanceclosest_clinic_hospitalOrganisationID
0John Smith462643.228292363859.7580577286.685059463764351
1Greg Brown409324.103047464084.5085061561.915405388662389
\n", + "
" + ], + "text/plain": [ + " name northing easting distance \\\n", + "0 John Smith 462643.228292 363859.758057 7286.685059 \n", + "1 Greg Brown 409324.103047 464084.508506 1561.915405 \n", + "\n", + " closest_clinic_hospital OrganisationID \n", + "0 4637 64351 \n", + "1 3886 62389 " + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# DO NOT CHANGE THIS CELL\n", + "patients=[\n", + " {\n", + " \"name\":\"John Smith\", \n", + " \"northing\":462643.2282915547,\n", + " \"easting\":363859.7580565622\n", + " }, \n", + " {\n", + " \"name\":\"Greg Brown\", \n", + " \"northing\":409324.1030472915,\n", + " \"easting\":464084.5085059871\n", + " }\n", + "]\n", + "\n", + "patients_df=pd.DataFrame(patients)\n", + "\n", + "patients_df['distance'], patients_df['closest_clinic_hospital'] = knn.kneighbors(patients_df[['northing', 'easting']])\n", + "\n", + "patients_df['OrganisationID'] = patients_df.apply(lambda x: all_med.loc[x['closest_clinic_hospital'], \"OrganisationID\"], axis=1)\n", + "\n", + "patients_df" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/lib/python3.10/site-packages/cudf/io/json.py:194: UserWarning: Using CPU via Pandas to write JSON dataset\n", + " warnings.warn(\"Using CPU via Pandas to write JSON dataset\")\n" + ] + } + ], + "source": [ + "patients_df.to_json('my_assessment/question_2.json', orient='records')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Check Submission ##" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{\"name\":\"John Smith\",\"northing\":462643.2282915547,\"easting\":363859.7580565622,\"distance\":7286.6850585938,\"closest_clinic_hospital\":4637,\"OrganisationID\":64351},{\"name\":\"Greg Brown\",\"northing\":409324.1030472915,\"easting\":464084.5085059871,\"distance\":1561.9154052734,\"closest_clinic_hospital\":3886,\"OrganisationID\":62389}]" + ] + } + ], + "source": [ + "!cat my_assessment/question_2.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Tip**: Your submission file should contain one line of text, similar to: \n", + "\n", + "```\n", + "[{'name':'John Smith','northing':XXX.XX,'easting':XXX.XX,'closest_clinic_hospital':XX,'OrganisationID':XX},{'name':'Greg Brown','northing':XXX.XX,'easting':XXX.XX,'closest_clinic_hospital':XX,'OrganisationID':XX}]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Please Restart the Kernel

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "...before moving to the next notebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import IPython\n", + "app = IPython.Application.instance()\n", + "app.kernel.do_shutdown(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Header\"" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.15" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/ds/25-1/2/4-04_identify_risk_factors.ipynb b/ds/25-1/2/4-04_identify_risk_factors.ipynb new file mode 100644 index 0000000..552c7ed --- /dev/null +++ b/ds/25-1/2/4-04_identify_risk_factors.ipynb @@ -0,0 +1,1212 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Header\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Week 3: Identify Risk Factors for Infection" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "**UPDATE**\n", + "\n", + "Thank you again for the previous analysis. We will next be publishing a public health advisory that warns of specific infection risk factors of which individuals should be aware. Please advise as to which population characteristics are associated with higher infection rates. \n", + "\n", + "\n", + "Your goal for this notebook will be to identify key potential demographic and economic risk factors for infection by comparing the infected and uninfected populations." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext cudf.pandas\n", + "import pandas as pd\n", + "import cuml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Begin by loading the data you've received about week 3 of the outbreak into a cuDF-accelerated pandas DataFrame. The data is located at `./data/week3.csv`. For this notebook you will need all columns of the data." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
agesexemploymentinfected
00mU0.0
10mU0.0
20mU0.0
30mU0.0
40mU0.0
...............
5847988990fV0.0
5847989090fV0.0
5847989190fV0.0
5847989290fV0.0
5847989390fV0.0
\n", + "

58479894 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " age sex employment infected\n", + "0 0 m U 0.0\n", + "1 0 m U 0.0\n", + "2 0 m U 0.0\n", + "3 0 m U 0.0\n", + "4 0 m U 0.0\n", + "... ... .. ... ...\n", + "58479889 90 f V 0.0\n", + "58479890 90 f V 0.0\n", + "58479891 90 f V 0.0\n", + "58479892 90 f V 0.0\n", + "58479893 90 f V 0.0\n", + "\n", + "[58479894 rows x 4 columns]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv('./data/week3.csv')\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Calculate Infection Rates by Employment Code" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Convert the `infected` column to type `float32`. For people who are not infected, the float32 `infected` value should be `0.0`, and for infected people it should be `1.0`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
agesexemploymentinfected
00mU0.0
10mU0.0
20mU0.0
30mU0.0
40mU0.0
...............
5847988990fV0.0
5847989090fV0.0
5847989190fV0.0
5847989290fV0.0
5847989390fV0.0
\n", + "

58479894 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " age sex employment infected\n", + "0 0 m U 0.0\n", + "1 0 m U 0.0\n", + "2 0 m U 0.0\n", + "3 0 m U 0.0\n", + "4 0 m U 0.0\n", + "... ... .. ... ...\n", + "58479889 90 f V 0.0\n", + "58479890 90 f V 0.0\n", + "58479891 90 f V 0.0\n", + "58479892 90 f V 0.0\n", + "58479893 90 f V 0.0\n", + "\n", + "[58479894 rows x 4 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['infected'] = df['infected'].astype('float32')\n", + "df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, produce a list of employment types and their associated **rates** of infection, sorted from highest to lowest rate of infection.\n", + "\n", + "**NOTE**: The infection **rate** for each employment type should be the percentage of total individuals within an employment type who are infected. Therefore, if employment type \"X\" has 1000 people, and 10 of them are infected, the infection **rate** would be .01. If employment type \"Z\" has 10,000 people, and 50 of them are infected, the infection rate would be .005, and would be **lower** than for type \"X\", even though more people within that employment type were infected." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
infected
employment
A0.003853
B, D, E0.003774
C0.003882
F0.003182
G0.004948
H0.003388
I0.010354
J0.003939
K0.004772
L0.004970
M0.004777
N0.004784
O0.005284
P0.006190
Q0.012756
R, S, T0.005390
U0.000217
V0.007590
X0.004539
Z0.005655
\n", + "
" + ], + "text/plain": [ + " infected\n", + "employment \n", + "A 0.003853\n", + "B, D, E 0.003774\n", + "C 0.003882\n", + "F 0.003182\n", + "G 0.004948\n", + "H 0.003388\n", + "I 0.010354\n", + "J 0.003939\n", + "K 0.004772\n", + "L 0.004970\n", + "M 0.004777\n", + "N 0.004784\n", + "O 0.005284\n", + "P 0.006190\n", + "Q 0.012756\n", + "R, S, T 0.005390\n", + "U 0.000217\n", + "V 0.007590\n", + "X 0.004539\n", + "Z 0.005655" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "emp_groups = df[['employment', 'infected']].groupby(['employment'])\n", + "emp_rate_df = emp_groups.mean()\n", + "emp_rate_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, read in the employment codes guide from `./data/code_guide.csv` to interpret which employment types are seeing the highest rates of infection." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CodeField
0AAgriculture, forestry & fishing
1B, D, EMining, energy and water supply
2CManufacturing
3FConstruction
4GWholesale, retail & repair of motor vehicles
5HTransport & storage
6IAccommodation & food services
7JInformation & communication
8KFinancial & insurance activities
9LReal estate activities
10MProfessional, scientific & technical activities
11NAdministrative & support services
12OPublic admin & defence; social security
13PEducation
14QHuman health & social work activities
15R, S, TOther services
16UStudent
17VRetired
18XOutside the UK or not specified
19YPre-school child
20ZNot formally employed
\n", + "
" + ], + "text/plain": [ + " Code Field\n", + "0 A Agriculture, forestry & fishing\n", + "1 B, D, E Mining, energy and water supply\n", + "2 C Manufacturing\n", + "3 F Construction\n", + "4 G Wholesale, retail & repair of motor vehicles\n", + "5 H Transport & storage\n", + "6 I Accommodation & food services\n", + "7 J Information & communication\n", + "8 K Financial & insurance activities\n", + "9 L Real estate activities\n", + "10 M Professional, scientific & technical activities\n", + "11 N Administrative & support services\n", + "12 O Public admin & defence; social security\n", + "13 P Education\n", + "14 Q Human health & social work activities\n", + "15 R, S, T Other services\n", + "16 U Student\n", + "17 V Retired\n", + "18 X Outside the UK or not specified\n", + "19 Y Pre-school child\n", + "20 Z Not formally employed" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "emp_codes = pd.read_csv('./data/code_guide.csv')\n", + "emp_codes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Get Top 2 Employment Type with Highest Rate of Infection ###" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we ask you to get the top two employment types that have the highest rate of infection. We start by using `.sort_values()` to sort `emp_rate_df` by the rate of infection. We then take the first 2 results. \n", + "\n", + "We will also need to index `emp_codes` to get the respeictve field name. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6 Accommodation & food services\n", + "14 Human health & social work activities\n", + "Name: Field, dtype: object" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "top_inf_emp = emp_rate_df.sort_values('infected', ascending=False).iloc[[0, 1]].index\n", + "top_inf_emp_df = emp_codes.loc[emp_codes['Code'].isin(top_inf_emp), 'Field']\n", + "top_inf_emp_df" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/lib/python3.10/site-packages/cudf/io/json.py:194: UserWarning: Using CPU via Pandas to write JSON dataset\n", + " warnings.warn(\"Using CPU via Pandas to write JSON dataset\")\n" + ] + } + ], + "source": [ + "top_inf_emp_df.to_json('my_assessment/question_3.json', orient='records')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Calculate Infection Rates by Employment Code and Sex" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We want to see if there is an effect of `sex` on infection rate, either in addition to `employment` or confounding it. Group by both `employment` and `sex` simultaneously to get the infection rate for the intersection of those categories." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ageinfected
employmentsex
If41.3776270.015064
Qf41.3854000.014947
Vf76.0222140.010852
B, D, Ef41.4256180.007973
R, S, Tf41.3716720.007748
Of41.3962460.007719
Kf41.3774950.007672
Mf41.4018980.007645
Jf41.3857720.007645
Cf41.3913650.007630
Zf41.3846180.007629
Pf41.3993020.007584
Ff41.4151910.007577
Gf41.3948930.007556
Af41.3850100.007491
Xf41.4014470.007391
Nf41.3865650.007389
Hf41.4168570.007385
Lf41.4123150.007221
Qm41.0158710.005120
Im40.9843400.005117
Vm74.9623310.003685
Gm41.0011630.002596
Pm40.9736410.002577
Cm40.9978510.002569
Jm41.0078000.002546
Om41.0179590.002543
Zm41.0107870.002543
R, S, Tm41.0216420.002542
Nm40.9753320.002538
Fm41.0074580.002535
Mm40.9895910.002520
Am40.9922020.002514
Km40.9886830.002490
Hm40.9787310.002482
B, D, Em41.0140250.002462
Xm41.0242420.002435
Lm40.9534360.002197
Uf8.3302510.000329
m8.3312350.000110
\n", + "
" + ], + "text/plain": [ + " age infected\n", + "employment sex \n", + "I f 41.377627 0.015064\n", + "Q f 41.385400 0.014947\n", + "V f 76.022214 0.010852\n", + "B, D, E f 41.425618 0.007973\n", + "R, S, T f 41.371672 0.007748\n", + "O f 41.396246 0.007719\n", + "K f 41.377495 0.007672\n", + "M f 41.401898 0.007645\n", + "J f 41.385772 0.007645\n", + "C f 41.391365 0.007630\n", + "Z f 41.384618 0.007629\n", + "P f 41.399302 0.007584\n", + "F f 41.415191 0.007577\n", + "G f 41.394893 0.007556\n", + "A f 41.385010 0.007491\n", + "X f 41.401447 0.007391\n", + "N f 41.386565 0.007389\n", + "H f 41.416857 0.007385\n", + "L f 41.412315 0.007221\n", + "Q m 41.015871 0.005120\n", + "I m 40.984340 0.005117\n", + "V m 74.962331 0.003685\n", + "G m 41.001163 0.002596\n", + "P m 40.973641 0.002577\n", + "C m 40.997851 0.002569\n", + "J m 41.007800 0.002546\n", + "O m 41.017959 0.002543\n", + "Z m 41.010787 0.002543\n", + "R, S, T m 41.021642 0.002542\n", + "N m 40.975332 0.002538\n", + "F m 41.007458 0.002535\n", + "M m 40.989591 0.002520\n", + "A m 40.992202 0.002514\n", + "K m 40.988683 0.002490\n", + "H m 40.978731 0.002482\n", + "B, D, E m 41.014025 0.002462\n", + "X m 41.024242 0.002435\n", + "L m 40.953436 0.002197\n", + "U f 8.330251 0.000329\n", + " m 8.331235 0.000110" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "simul_groups = df.groupby(['employment', 'sex'])\n", + "simul_groups.mean().sort_values('infected', ascending=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Check Submission ##" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[\"Accommodation & food services\",\"Human health & social work activities\"]" + ] + } + ], + "source": [ + "!cat my_assessment/question_3.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Tip**: Your submission file should contain one line of text, similar to: \n", + "\n", + "```\n", + "[\"Agriculture, forestry & fishing\",\"Mining, energy and water supply\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Please Restart the Kernel

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you plan to continue work in other notebooks, please shutdown the kernel." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'status': 'ok', 'restart': True}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import IPython\n", + "app = IPython.Application.instance()\n", + "app.kernel.do_shutdown(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Header\"" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.15" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}