import streamlit as st import pandas as pd import numpy as np import base64, pickle import plotly.express as px from streamlit_plotly_events import plotly_events # --------------------------------------------------- # Decode embedded data # --------------------------------------------------- filled_matrices_encoded = "gASVhzAAAAAAAAB9lCiMCVlhbyBaaGVuZ5SMEXBhbmRhcy5jb3JlLmZyYW1llIwJRGF0YUZyYW1llJOUKYGUfZQojARfbWdylIwecGFuZGFzLmNvcmUuaW50ZXJuYWxzLm1hbmFnZXJzlIwMQmxvY2tNYW5hZ2VylJOUjBZwYW5kYXMuX2xpYnMuaW50ZXJuYWxzlIwPX3VucGlja2xlX2Jsb2NrlJOUjBZudW1weS5fY29yZS5tdWx0aWFycmF5lIwMX3JlY29uc3RydWN0lJOUjAVudW1weZSMB25kYXJyYXmUk5RLAIWUQwFilIeUUpQoSwFLBEsHhpRoEYwFZHR5cGWUk5SMAmY4lImIh5RSlChLA4wBPJROTk5K/////0r/////SwB0lGKIQ+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPw/AAAAAAAAC0AAAAAAAADYPwAAAAAAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOg/AAAAAAAA0D8AAAAAAAAAAAAAAAAAAMA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2D8AAAAAAADAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJR0lGKMCGJ1aWx0aW5zlIwFc2xpY2WUk5RLAEsESwGHlFKUSwKHlFKUhZRdlCiMGHBhbmRhcy5jb3JlLmluZGV4ZXMuYmFzZZSMCl9uZXdfSW5kZXiUk5RoK4wFSW5kZXiUk5R9lCiMBGRhdGGUaBBoE0sAhZRoFYeUUpQoSwFLBIWUaBqMAk84lImIh5RSlChLA4wBfJROTk5K/////0r/////Sz90lGKJXZQojBJBZHZhbmNpbmcgYXV0b25vbXmUjCdJbnRlcmFjdGluZyB3aXRoIG9yZ2FuaWMvbGl2aW5nIHN5c3RlbXOUjBVBaWRpbmcgc3VzdGFpbmFiaWxpdHmUjBtHcm93aW5nIHRoZSBpbmZvcm1hdGlvbiBhZ2WUZXSUYowEbmFtZZROdYaUUpRoLWgvfZQoaDFoEGgTSwCFlGgVh5RSlChLAUsHhZRoOIldlCiMbU5hbm8gbWF0ZXJpYWxzLCBmYWJyaWNhdGlvbiAmIGRldmljZXMgKGVsZWN0cm9uaWMsIHBob3RvbmljIGFuZCBiaW9sb2dpY2FsKSwgaGV0ZXJvZ2VuZW91cyBzeXN0ZW0gaW50ZWdyYXRpb26UjFxTZW5zaW5nLCBzdGltdWxhdGlvbiwgY29tbXVuaWNhdGlvbiAoZWxlY3Ryb25pYywgcGhvdG9uaWMsIGJpb2xvZ2ljYWwpLCBhbGwgZm9ybXMgb2YgaW1hZ2luZ5SMLlF1YW50dW0gZW5naW5lZXJpbmcgYW5kIGluZm9ybWF0aW9uIHByb2Nlc3NpbmeUjCdFbmVyZ3kgY29udmVyc2lvbiwgdHJhbnNmZXIgYW5kIHN0b3JhZ2WUjENFeHRyYWN0aW5nIGluZm9ybWF0aW9uIGZyb20gZGF0YSwgZGF0YSBzY2llbmNlIGFuZCBtYWNoaW5lIGxlYXJuaW5nlIxqQ29tcGxleCBzeXN0ZW0gZGVzaWduLCBjb250cm9sIGFuZCBvcHRpbWl6YXRpb24sIGluY2x1ZGluZyBuZXR3b3Jrcywgc2VjdXJpdHksIHByaXZhY3ksIHNhZmV0eSwgcm9idXN0bmVzc5SMTUNvbXB1dGluZyBzeXN0ZW1zIGFuZCBhcmNoaXRlY3R1cmUsIGRlc2lnbiBhdXRvbWF0aW9uIGFsZ29yaXRobXMgYW5kIHNvZnR3YXJllGV0lGJoQU51hpRSlGWGlFKUjARfdHlwlIwJZGF0YWZyYW1llIwJX21ldGFkYXRhlF2UjAVhdHRyc5R9lIwGX2ZsYWdzlH2UjBdhbGxvd3NfZHVwbGljYXRlX2xhYmVsc5SIc3VijAtIYW95dWUgVGFuZ5RoBCmBlH2UKGgHaApoDWgQaBNLAIWUaBWHlFKUKEsBSwRLB4aUaB2IQ+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANA/AAAAAAAAAAAAAAAAAADAPwAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwD8AAAAAAADgPwAAAAAAAOw/AAAAAAAAAAAAAAAAAADAPwAAAAAAAAxAAAAAAAAAwD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA8j8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwD8A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" df_encoded = "gASVJhkAAAAAAACMEXBhbmRhcy5jb3JlLmZyYW1llIwJRGF0YUZyYW1llJOUKYGUfZQojARfbWdylIwecGFuZGFzLmNvcmUuaW50ZXJuYWxzLm1hbmFnZXJzlIwMQmxvY2tNYW5hZ2VylJOUjBZwYW5kYXMuX2xpYnMuaW50ZXJuYWxzlIwPX3VucGlja2xlX2Jsb2NrlJOUjBZudW1weS5fY29yZS5tdWx0aWFycmF5lIwMX3JlY29uc3RydWN0lJOUjAVudW1weZSMB25kYXJyYXmUk5RLAIWUQwFilIeUUpQoSwFLBksZhpRoD4wFZHR5cGWUk5SMAk84lImIh5RSlChLA4wBfJROTk5K/////0r/////Sz90lGKJXZQojApBYXJvbiBPaHRhlIwTQW5kZXJzIEjDuHN0LU1hZHNlbpSMC0FudGhvbnkgS3VolIwNQm9yaXMgTXVybWFubpSMC0RhaXN5IEdyZWVulIwLRGFuaWVsIERyZXeUjA5EYXJyZW4gQ2FybHNvbpSMDEdhbGVuIFNhc2FraZSMDkfDvHJkYWwgQXJzbGFulIwLSGFucWluZyBHdW+UjApIYW9mYW4gQ2FplIwLSGFveXVlIFRhbmeUjAxJZ29yIE1vbHlib2eUjA5KZWZmcmV5IFdlbGRvbpSMDEplbm5pZmVyIE90dJSMCkp1bmUgWmhhbmeUjApMaXV3YW4gWmh1lIwNTXVyYWQgSG9zc2FpbpSMGU5hcmF5YW5hIFByYXNhZCBTYW50aGFuYW2UjBNPbGdhIEJvcmnEhy1MdWJlY2tllIwRVmljdG9yIE0uIEx1YmVja2WUjA5WaW5vZCBNYWxob3RyYZSMEFdheW5lIEEuIFNoaXJvbWGUjAlZYW8gWmhlbmeUjAxZaW5nZmVpIERvbmeUjAJFUJSMA1NEU5RoOWg4aDloOYwEQ0VOR5RoOmg5aDpoOmg5aDloOGg4aDloOmg5aDloOGg4aDhoOGg6aDqMBlNlbmlvcpRoO2g7aDuMBkp1bmlvcpRoPGg8jAZNaWRkbGWUaD1oPGg8aDxoPGg9aDxoPWg8aDxoO2g7aDtoPWg7aD1oO4wTTUVNUyAmIE1pY3JvZGV2aWNlc5SMIkNvbW11bmljYXRpb25zICYgU2lnbmFsIFByb2Nlc3NpbmeUjCRTaWduYWwgUHJvY2Vzc2luZyAmIE1hY2hpbmUgTGVhcm5pbmeUjB5BbmFsb2cgJiBNaXhlZC1TaWduYWwgQ2lyY3VpdHOUjCJTaWduYWwgUHJvY2Vzc2luZyAmIEVuZXJneSBTeXN0ZW1zlIwSUm9ib3RpY3MgJiBDb250cm9slIwcQ3liZXItUGh5c2ljYWwgJiBJb1QgU3lzdGVtc5SMFkNvbW11bmljYXRpb24gTmV0d29ya3OUjA9Db250cm9sIFN5c3RlbXOUjBJDeWJlcnNlY3VyaXR5ICYgQUmUjBNXaXJlbGVzcyBOZXR3b3JraW5nlIwRQUkgJiBPcHRpbWl6YXRpb26UaEmMFk5hbm9lbGVjdHJvbmljcyAmIENNT1OUjBNTb2xpZC1TdGF0ZSBEZXZpY2VzlIwWRGF0YSAmIE5ldHdvcmsgU2NpZW5jZZSMC0FJIFNlY3VyaXR5lIwWQmlvbWVkaWNhbCBFbmdpbmVlcmluZ5SMHUluZm9ybWF0aW9uIFRoZW9yeSAmIExlYXJuaW5nlIwiTWljcm93YXZlICYgQmlvbWVkaWNhbCBFbmdpbmVlcmluZ5SMH01pY3Jvd2F2ZSBFbmdpbmVlcmluZyAmIFNlbnNvcnOUjCFTZW1pY29uZHVjdG9yIERldmljZXMgJiBQaG90b25pY3OUjBVNaWNyb3dhdmUgRW5naW5lZXJpbmeUjBhXaXJlbGVzcyBDb21tICYgU2VjdXJpdHmUjBhOZXR3b3JrcyAmIEN5YmVyc2VjdXJpdHmUjG9NaWNyb2ZhYnJpY2F0ZWQgZGV2aWNlczsgTUVNUzsgYmlvbWVkaWNhbCBtaWNyb2RldmljZXM7IG1pY3JvZmx1aWRpY3M7IG9wdG9mbHVpZGljczsgcmVjb25maWd1cmFibGUgZWxlY3Ryb25pY3OUjEpTdGF0aXN0aWNhbCBzaWduYWwgcHJvY2Vzc2luZzsgaW5mb3JtYXRpb24gdGhlb3J5OyB3aXJlbGVzcyBjb21tdW5pY2F0aW9uc5SMYk5ldXJhbCBuZXR3b3JrczsgbWFjaGluZSBsZWFybmluZzsgYWRhcHRpdmUgc2lnbmFsIHByb2Nlc3Npbmc7IHNlbnNvciBuZXR3b3Jrczsgc21hcnQgZ3JpZCBzeXN0ZW1zlIxvTWl4ZWQtc2lnbmFsIElDIGRlc2lnbjsgc2Vuc29yIGludGVyZmFjZXM7IEEvRCBhbmQgRC9BIGNvbnZlcnRlcnM7IGhpZ2gtc3BlZWQgbGlua3M7IFRpbnlNTCBoYXJkd2FyZTsgRURBIHRvb2xzlIxnU2lnbmFsIHByb2Nlc3Npbmc7IGVzdGltYXRpb247IG1hY2hpbmUgbGVhcm5pbmc7IGNvbnRyb2wgZm9yIGNvbmRpdGlvbiBtb25pdG9yaW5nIGFuZCBlbmVyZ3kgbWFuYWdlbWVudJSMUkF1dG9ub21vdXMgbWljcm8tcm9ib3RzOyBtdWx0aS1yb2JvdCBzeXN0ZW1zOyBjb250aW51dW0gcm9ib3RpY3M7IGFkYXB0aXZlIGNvbnRyb2yUjGtDeWJlci1waHlzaWNhbCBzeXN0ZW1zOyB1YmlxdWl0b3VzIGNvbXB1dGluZzsgSW50ZXJuZXQgb2YgVGhpbmdzOyBlZGdlIGNvbXB1dGluZzsgaW50ZXJhY3RpdmUgZGlnaXRhbCBtZWRpYZSMWENvbW11bmljYXRpb24gbmV0d29ya3M7IG9wdGljYWwgbmV0d29ya2luZzsgbmV0d29yayBvcHRpbWl6YXRpb247IHBlcmZvcm1hbmNlIGV2YWx1YXRpb26UjDdDb29wZXJhdGl2ZSBtdWx0aS1hZ2VudCBzeXN0ZW1zOyBnYW1lLXRoZW9yZXRpYyBjb250cm9slIwtQ3liZXJzZWN1cml0eTsgdHJ1c3R3b3J0aHkgQUk7IG1vYmlsZSBzZW5zaW5nlIxLV2lyZWxlc3MgbmV0d29ya2luZzsgSW50ZXJuZXQgb2YgVGhpbmdzOyBtb2JpbGUgY29tcHV0aW5nOyBuZXR3b3JrIHNlY3VyaXR5lIxTSW5mb3JtYXRpb24gdGhlb3J5OyBzdG9jaGFzdGljIG9wdGltaXphdGlvbjsgc2VtYW50aWMgbmV0d29ya2luZzsgZ2VuZXJhdGl2ZSBtb2RlbHOUjF9TY2FsYWJsZSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobXM7IGdlbmVyYXRpdmUgQUkgdHJhaW5pbmc7IG9wdGltaXphdGlvbiBmb3IgbGVhcm5pbmcgc3lzdGVtc5SMdU5hbm9zY2FsZSBkZXZpY2UgZGVzaWduOyBlbWVyZ2luZyBzZW1pY29uZHVjdG9yIHRlY2hub2xvZ2llczsgaGV0ZXJvZ2VuZW91cyBDTU9TIGludGVncmF0aW9uOyBuYW5vLWJpb21lZGljYWwgZGV2aWNlc5SMTlNlbWljb25kdWN0b3IgZGV0ZWN0b3JzOyBvcHRvZWxlY3Ryb25pY3M7IHJhZGlhdGlvbiBkZXRlY3Rpb247IHF1YW50dW0gZGV2aWNlc5SMZEdyYXBoIHNpZ25hbCBwcm9jZXNzaW5nOyBuZXR3b3JrIHNjaWVuY2U7IGRhdGEgYW5hbHl0aWNzOyBiaW9pbmZvcm1hdGljczsgaHVtYW4tY29tcHV0ZXIgaW50ZXJhY3Rpb26UjDpNYWNoaW5lIGxlYXJuaW5nIGZvciBjeWJlcnNlY3VyaXR5OyBzZWN1cml0eSBvZiBBSSBzeXN0ZW1zlIxeVWx0cmFzb3VuZC1iYXNlZCBkaWFnbm9zdGljcyBhbmQgdGhlcmFweTsgZWxhc3RvZ3JhcGh5OyBiaW9tZWRpY2FsIHNpZ25hbCBhbmQgaW1hZ2UgcHJvY2Vzc2luZ5SMXVN0YXRpc3RpY2FsIGxlYXJuaW5nIHRoZW9yeTsgaW5mb3JtYXRpb24gdGhlb3J5OyBoaWdoLWRpbWVuc2lvbmFsIHN0YXRpc3RpY3M7IG9ubGluZSBsZWFybmluZ5SMWFNpbGljb24gUkYvaGlnaC1mcmVxdWVuY3kgaW50ZWdyYXRlZCBjaXJjdWl0czsgYmlvbWVkaWNhbCBhcHBsaWNhdGlvbnM7IHJlbmV3YWJsZSBlbmVyZ3mUjGJSZW1vdGUgc2Vuc2luZyBhbmQgaW1hZ2luZzsgYmlvbWVkaWNhbCBzZW5zb3JzOyBhbmltYWwgdHJhY2tpbmc7IE1FTVM7IG1pY3Jvd2F2ZS90ZXJhaGVydHogc3lzdGVtc5SMVENvbXBvdW5kIHNlbWljb25kdWN0b3IgZGV2aWNlczsgc3VyZmFjZSBwYXNzaXZhdGlvbjsgcGhvdG9uaWMvb3B0b2VsZWN0cm9uaWMgZGV2aWNlc5SMSE1pY3Jvd2F2ZSBhbmQgbWlsbGltZXRlci13YXZlIGVsZWN0cm9uaWNzOyBxdWFzaS1vcHRpY2FsIHBvd2VyIGNvbWJpbmluZ5SMPFdpcmVsZXNzIGNvbW11bmljYXRpb25zOyB3aXJlbGVzcyBzZW5zaW5nOyB3aXJlbGVzcyBzZWN1cml0eZSMYUNvbXB1dGVyIGFuZCBuZXR3b3JrIHNlY3VyaXR5OyBwcml2YWN5OyBjb21wdXRlciBuZXR3b3JrczsgSW50ZXJuZXQgc2VydmljZXM7IGRpc3RyaWJ1dGVkIHN5c3RlbXOUjGZNaWNyb3JvYm90aWNzIHdpdGggbWljcm9mbHVpZGljczsgbGFiLW9uLWEtY2hpcCBiaW9tZWRpY2FsIGRldmljZXM7IHJlY29uZmlndXJhYmxlIG9wdG9mbHVpZGljIHN5c3RlbXOUjI1XaXJlbGVzcyBuZXR3b3JrIGNvb3BlcmF0aW9uOyBoZWFydCBtb25pdG9yaW5nIHZpYSB3aXJlbGVzcyBzZW5zb3JzOyB1bmRlcndhdGVyIGFjb3VzdGljIGNvbW11bmljYXRpb25zOyBiaWcgZGF0YSBhbmFseXRpY3MgaW4gY29tbXVuaWNhdGlvbnOUjE5EaXN0cmlidXRlZCBsZWFybmluZyBpbiBzZW5zb3IgbmV0d29ya3M7IHJlbmV3YWJsZSBlbmVyZ3kgc21hcnQgZ3JpZCBhbmFseXRpY3OUjGhFbWJlZGRlZCBtYWNoaW5lIGxlYXJuaW5nIGFjY2VsZXJhdG9ycyAoVGlueU1MKTsgb3Blbi1zb3VyY2UgY2hpcCBkZXNpZ247IGFkdmFuY2VkIGRhdGEgY29udmVydGVyIGRlc2lnbpSMM0J1aWxkaW5nIGVuZXJneSBtb25pdG9yaW5nOyBzbWFydCBncmlkIG9wdGltaXphdGlvbpSMUkluc2VjdC1zY2FsZSByb2JvdHM7IG11bHRpLXJvYm90IHNlbnNvciBkZXBsb3ltZW50OyBtaWNyb3N1cmdpY2FsIGNvbnRpbnV1bSByb2JvdHOUjEVBbWJpZW50IGNvbXB1dGluZyBmcmFtZXdvcmtzIGZvciBJb1Q7IHBoeXNpY2FsIHVzZXIgZXhwZXJpZW5jZSBkZXNpZ26UjE9PcHRpY2FsIG5ldHdvcmsgcm91dGluZyBvcHRpbWl6YXRpb247IGhpZ2gtc3BlZWQgbmV0d29yayByZWxpYWJpbGl0eSBhbGdvcml0aG1zlIxsQXV0b25vbW91cyByZXNvdXJjZSBhbGxvY2F0aW9uOyBtdWx0aS1zZW5zb3IgZGVwbG95bWVudDsgdHJhZmZpYyBtYW5hZ2VtZW50OyBjb29wZXJhdGl2ZSBNSU1PIGNvbW11bmljYXRpb25zlIxgU2VjdXJpdHkgYW5kIHByaXZhY3kgaW4gQUktZW5hYmxlZCBzeXN0ZW1zIChzbWFydCBhdXRoZW50aWNhdGlvbiwgdm9pY2UgYXNzaXN0YW50cywgSW9UIGRldmljZXMplIwpSW9UIGNvbm5lY3Rpdml0eTsgbW9iaWxlIG5ldHdvcmsgc2VjdXJpdHmUjIBEYXRhIGZyZXNobmVzcyBvcHRpbWl6YXRpb247IHNlbWFudGljIHNlbnNpbmcgYW5kIGRhdGEgcmV0cmlldmFsOyBkaWZmdXNpb24tYmFzZWQgaW1hZ2UgaW52ZXJzaW9uOyByaXNrLWF3YXJlIG5ldHdvcmsgc2NoZWR1bGluZ5SMYkVmZmljaWVudCB0cmFpbmluZyBvZiBsYXJnZSBUcmFuc2Zvcm1lciBtb2RlbHM7IG9wdGltaXphdGlvbiBtZXRob2RzIGZvciBoaWdoLWRpbWVuc2lvbmFsIGxlYXJuaW5nlIxVQ2FyYm9uIG5hbm90dWJlIFJGIGNpcmN1aXRzOyBDTU9TIGZvciBkYXRhLWludGVuc2l2ZSBjb21wdXRpbmc7IG5hbm8tc2NhbGUgYmlvc2Vuc29yc5SMdVNpbGljb24gcGl4ZWwgc2Vuc29ycyBmb3IgcGFydGljbGUgcGh5c2ljczsgcHJlY2lzaW9uIHRpbWluZyBzZW5zb3IgZGVzaWduOyBhZHZhbmNlZCB0aGluLWZpbG0gbWF0ZXJpYWxzIGluIGRldGVjdG9yc5SMY01vZGVsaW5nIGxhcmdlLXNjYWxlIHNvY2lhbC9iaW9sb2dpY2FsIG5ldHdvcmtzOyBhbmFseXppbmcgaW5kaXZpZHVhbC10by1uZXR3b3JrIGJlaGF2aW9yYWwgZWZmZWN0c5SMVkFkdmVyc2FyaWFsIGFuZCBiYWNrZG9vciBhdHRhY2tzIG9uIEFJIG1vZGVsczsgZGVlcCBsZWFybmluZy1iYXNlZCBpbnRydXNpb24gZGV0ZWN0aW9ulIxvVWx0cmFzb3VuZCBlbGFzdG9ncmFwaHkgZm9yIG9yZ2FuIGhlYWx0aDsgYnJlYXN0IGNhbmNlciBpbWFnaW5nIGFuZCB0aGVyYXB5OyBmb2N1c2VkIHVsdHJhc291bmQgbmV1cm9tb2R1bGF0aW9ulIxvVW5pdmVyc2FsIGRhdGEgY29tcHJlc3Npb247IGZ1bmRhbWVudGFsIGxpbWl0cyBvZiBzZXF1ZW50aWFsIGxlYXJuaW5nOyBjb21wbGV4aXR5IG9mIHNhbXBsaW5nIGluIGxhcmdlIG5ldHdvcmtzlIw1Tm9uLWNvbnRhY3Qgdml0YWwgc2lnbiBkZXRlY3Rpb247IHdlYXJhYmxlIGJpb3NlbnNvcnOUjFZOb24taW52YXNpdmUgdml0YWwgc2lnbiBtb25pdG9yaW5nOyBVQVYtYmFzZWQgc2Vuc29yIHN5c3RlbXM7IHRlcmFoZXJ0eiB3aXJlbGVzcyBsaW5rc5SMQUdhQXMvSW5QIHN1cmZhY2UgcGFzc2l2YXRpb24gdGVjaG5pcXVlczsgbG93LXBvd2VyIHBob3RvZGV0ZWN0b3JzlIxHU2F0ZWxsaXRlIGNvbW11bmljYXRpb24gYW1wbGlmaWVyczsgbWlsbGltZXRlci13YXZlIGNpcmN1aXQgaW50ZWdyYXRpb26UjFRJb1Qgc2Vuc2luZyBuZXR3b3JrczsgcGh5c2ljYWwtbGF5ZXIgd2lyZWxlc3Mgc2VjdXJpdHk7IGRyb25lIGNvbW11bmljYXRpb24gc2VjdXJpdHmUjF1Bbm9ueW1vdXMgY29tbXVuaWNhdGlvbnM7IGNsb3VkIGFuZCBJb1Qgc2VjdXJpdHk7IFVBViBuZXR3b3JrIHNlY3VyaXR5OyBzbWFydCBncmlkIHByb3RlY3Rpb26UZXSUYowIYnVpbHRpbnOUjAVzbGljZZSTlEsASwZLAYeUUpRLAoeUUpSFlF2UKIwYcGFuZGFzLmNvcmUuaW5kZXhlcy5iYXNllIwKX25ld19JbmRleJSTlGiSjAVJbmRleJSTlH2UKIwEZGF0YZRoDmgRSwCFlGgTh5RSlChLAUsGhZRoG4ldlCiMBE5hbWWUjApEZXB0IFRyYWNrlIwIU3RhbmRpbmeUjAVUcmFja5SMElJlc2VhcmNoIEludGVyZXN0c5SMFlJlY2VudCBSZXNlYXJjaCBUb3BpY3OUZXSUYowEbmFtZZROdYaUUpRolIwZcGFuZGFzLmNvcmUuaW5kZXhlcy5yYW5nZZSMClJhbmdlSW5kZXiUk5R9lChopU6MBXN0YXJ0lEsAjARzdG9wlEsZjARzdGVwlEsBdYaUUpRlhpRSlIwEX3R5cJSMCWRhdGFmcmFtZZSMCV9tZXRhZGF0YZRdlIwFYXR0cnOUfZSMBl9mbGFnc5R9lIwXYWxsb3dzX2R1cGxpY2F0ZV9sYWJlbHOUiHN1Yi4=" filled_matrices = pickle.loads(base64.b64decode(filled_matrices_encoded)) df = pickle.loads(base64.b64decode(df_encoded)) # --------------------------------------------------- # Sidebar: Filters # --------------------------------------------------- st.sidebar.title("Filters") if st.sidebar.button("Clear All Filters"): st.experimental_rerun() standing_opts = sorted(df['Standing'].dropna().astype(str).unique()) dept_opts = sorted(df['Dept Track'].dropna().astype(str).unique()) standing_sel = st.sidebar.multiselect( "Filter by Standing:", standing_opts, default=standing_opts ) dept_sel = st.sidebar.multiselect( "Filter by Dept Track:", dept_opts, default=dept_opts ) # Auto‑filter names based on Standing & Dept mask = ( df['Standing'].astype(str).isin(standing_sel) & df['Dept Track'].astype(str).isin(dept_sel) ) all_names = sorted(df['Name'].astype(str).unique()) name_options = sorted(df.loc[mask, 'Name'].astype(str).unique()) name_sel = st.sidebar.multiselect( "Select Faculty:", name_options, default=name_options ) # --------------------------------------------------- # Main app # --------------------------------------------------- st.title("Faculty Heatmap Explorer") # 1) Heatmap if not name_sel: st.write("**No faculty selected** — please select at least one name.") fig = px.imshow( [[0]], labels={'x':'','y':'','color':'value'}, text_auto='.2f', title="No faculty selected" ) st.plotly_chart(fig, use_container_width=True) else: # Sum and average matrices sum_df = None for name in name_sel: mat = filled_matrices[name] sum_df = mat if sum_df is None else sum_df.add(mat, fill_value=0) avg_df = sum_df.div(len(name_sel)) fig = px.imshow( avg_df, x=avg_df.columns, y=avg_df.index, labels={'color':'Avg value'}, text_auto='.2f', title=f"Avg Heatmap for {len(name_sel)} Faculty" ) fig.update_yaxes(autorange='reversed') st.plotly_chart(fig, use_container_width=True) # 2) Click to show details st.subheader("Cell Details") events = plotly_events(fig, click_event=True, key="heatmap") if events: x_lab = events[0]['x'] y_lab = events[0]['y'] # Gather non-zero values records = [] for name in name_sel: val = filled_matrices[name].at[y_lab, x_lab] if val != 0: row = df[df['Name']==name].iloc[0] records.append({ 'Name': name, 'Value': val, 'Dept Track': str(row['Dept Track']), 'Standing': str(row['Standing']) }) if records: detail_df = pd.DataFrame(records) # Dept Track distribution dept_df = ( detail_df.groupby(['Dept Track','Value']) .size() .reset_index(name='Count') ) fig_dept = px.line( dept_df, x='Value', y='Count', color='Dept Track', markers=True, title=f"Distribution by Dept Track (x={x_lab}, y={y_lab})" ) st.plotly_chart(fig_dept, use_container_width=True) # Standing distribution stand_df = ( detail_df.groupby(['Standing','Value']) .size() .reset_index(name='Count') ) fig_st = px.line( stand_df, x='Value', y='Count', color='Standing', markers=True, title=f"Distribution by Standing (x={x_lab}, y={y_lab})" ) st.plotly_chart(fig_st, use_container_width=True) # Table of non-zero values table_df = detail_df[['Name','Value']].sort_values('Value', ascending=False) st.dataframe(table_df) else: st.write("**No non-zero values for this cell.**") else: st.write("Click on a heatmap cell to see Dept/Standing distributions & values.")