import streamlit as st import pandas as pd import numpy as np import base64, pickle, textwrap import plotly.express as px # --------------------------------------------------- # Page configuration for wide layout # --------------------------------------------------- st.set_page_config(page_title="Faculty Heatmap Explorer", layout="wide") # --------------------------------------------------- # 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)) # --------------------------------------------------- # Helper: wrap long labels # --------------------------------------------------- def wrap_labels(labels, width=40): return ["
".join(textwrap.wrap(lbl, width)) for lbl in labels] # --------------------------------------------------- # Sidebar: Filters # --------------------------------------------------- st.sidebar.title("Filters") def_opts = sorted(df['Dept Track'].dropna().astype(str).unique()) def_stand = sorted(df['Standing'].dropna().astype(str).unique()) # Clear filters button resets session state if st.sidebar.button("Clear All Filters"): st.session_state.pop('standing', None) st.session_state.pop('dept', None) st.session_state.pop('names', None) standing_sel = st.sidebar.multiselect( "Filter by Standing:", options=def_stand, default=st.session_state.get('standing', def_stand), key='standing' ) dept_sel = st.sidebar.multiselect( "Filter by Dept Track:", options=def_opts, default=st.session_state.get('dept', def_opts), key='dept' ) # Filter names based on selected Standing & Dept mask = ( df['Standing'].astype(str).isin(standing_sel) & df['Dept Track'].astype(str).isin(dept_sel) ) name_opts = sorted(df.loc[mask, 'Name'].astype(str).unique()) # Initialize or prune stored names if 'names' not in st.session_state or st.session_state.names is None: st.session_state.names = name_opts.copy() else: st.session_state.names = [n for n in st.session_state.names if n in name_opts] name_sel = st.sidebar.multiselect( "Select Faculty:", options=name_opts, default=st.session_state.names, key='names' ) # --------------------------------------------------- # Main app # --------------------------------------------------- st.title("Faculty Heatmap Explorer") # Display heatmap (with optional row sums) if not name_sel: st.warning("No faculty selected — please choose at least one.") 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: # Combine 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)) # Add a sum column on the right avg_df_ext = avg_df.copy() avg_df_ext['Sum'] = avg_df_ext.sum(axis=1) # Wrap y-axis labels for compact display wrapped_y = wrap_labels(list(avg_df_ext.index)) wrapped_x = list(avg_df_ext.columns) # Create heatmap fig = px.imshow( avg_df_ext.values, x=wrapped_x, y=wrapped_y, labels={'color':'Avg value'}, text_auto='.2f', title=f"Avg Heatmap for {len(name_sel)} Faculty" ) fig.update_yaxes(autorange='reversed') # Set a taller figure height for wide layout fig.update_layout(height=800, margin=dict(l=70, r=70, t=70, b=70)) st.plotly_chart(fig, use_container_width=True)