Files
JPMC-quant/theme.py
2026-02-03 01:32:06 +01:00

140 lines
4.8 KiB
Python

"""
Color palette and style definitions for Voice Branding analysis plots.
"""
class ColorPalette:
"""
Consistent color palette for all visualizations.
Update colors here to propagate changes to all plots.
"""
# Primary brand/chart color
PRIMARY = "#0077B6" # Medium Blue
# Gradient for rankings (Darkest -> Lightest or Strong -> Soft)
RANK_1 = "#004C6D" # Dark Blue (1st Choice)
RANK_2 = "#008493" # Teal (2nd Choice)
RANK_3 = "#5AAE95" # Sea Green (3rd Choice)
RANK_4 = "#9E9E9E" # Grey (4th Choice / Worst)
# Neutral color for unhighlighted comparison items
NEUTRAL = "#D3D3D3" # Light Grey
# Character-specific colors (for individual character plots)
# Each character has a main color and a lighter highlight for original traits
CHARACTER_BANK_TELLER = "#004C6D" # Dark Blue
CHARACTER_BANK_TELLER_HIGHLIGHT = "#669BBC" # Light Steel Blue
CHARACTER_FAMILIAR_FRIEND = "#008493" # Teal
CHARACTER_FAMILIAR_FRIEND_HIGHLIGHT = "#A8DADC" # Pale Cyan
CHARACTER_COACH = "#5AAE95" # Sea Green
CHARACTER_COACH_HIGHLIGHT = "#A8DADC" # Pale Cyan
CHARACTER_PERSONAL_ASSISTANT = "#457B9D" # Steel Blue
CHARACTER_PERSONAL_ASSISTANT_HIGHLIGHT = "#669BBC" # Light Steel Blue
# General UI elements
TEXT = "black"
GRID = "lightgray"
BACKGROUND = "white"
# Statistical significance colors (for heatmaps/annotations)
SIG_STRONG = "#004C6D" # p < 0.001 - Dark Blue (highly significant)
SIG_MODERATE = "#0077B6" # p < 0.01 - Medium Blue (significant)
SIG_WEAK = "#5AAE95" # p < 0.05 - Sea Green (marginally significant)
SIG_NONE = "#E8E8E8" # p >= 0.05 - Light Grey (not significant)
SIG_DIAGONAL = "#FFFFFF" # White for diagonal (self-comparison)
# Extended palette for categorical charts (e.g., pie charts with many categories)
CATEGORICAL = [
"#0077B6", # PRIMARY - Medium Blue
"#004C6D", # RANK_1 - Dark Blue
"#008493", # RANK_2 - Teal
"#5AAE95", # RANK_3 - Sea Green
"#9E9E9E", # RANK_4 - Grey
"#D3D3D3", # NEUTRAL - Light Grey
"#003049", # Dark Navy
"#669BBC", # Light Steel Blue
"#A8DADC", # Pale Cyan
"#457B9D", # Steel Blue
]
# Gender-based colors (Male = Blue tones, Female = Pink tones)
# Primary colors by gender
GENDER_MALE = "#0077B6" # Medium Blue (same as PRIMARY)
GENDER_FEMALE = "#B6007A" # Medium Pink
# Ranking colors by gender (Darkest -> Lightest)
GENDER_MALE_RANK_1 = "#004C6D" # Dark Blue
GENDER_MALE_RANK_2 = "#0077B6" # Medium Blue
GENDER_MALE_RANK_3 = "#669BBC" # Light Steel Blue
GENDER_FEMALE_RANK_1 = "#6D004C" # Dark Pink
GENDER_FEMALE_RANK_2 = "#B6007A" # Medium Pink
GENDER_FEMALE_RANK_3 = "#BC669B" # Light Pink
# Neutral colors by gender (for non-highlighted items)
GENDER_MALE_NEUTRAL = "#B8C9D9" # Grey-Blue
GENDER_FEMALE_NEUTRAL = "#D9B8C9" # Grey-Pink
# Speaking Style Colors (named after the style quadrant colors)
STYLE_GREEN = "#2E7D32" # Forest Green
STYLE_BLUE = "#1565C0" # Strong Blue
STYLE_ORANGE = "#E07A00" # Burnt Orange
STYLE_RED = "#C62828" # Deep Red
def jpmc_altair_theme():
"""JPMC brand theme for Altair charts."""
return {
'config': {
'view': {
'continuousWidth': 1000,
'continuousHeight': 500,
'strokeWidth': 0
},
'background': ColorPalette.BACKGROUND,
'axis': {
'grid': True,
'gridColor': ColorPalette.GRID,
'labelFontSize': 11,
'titleFontSize': 12,
'labelColor': ColorPalette.TEXT,
'titleColor': ColorPalette.TEXT,
'labelLimit': 200 # Allow longer labels before truncation
},
'axisX': {
'labelAngle': -45,
'labelLimit': 200 # Allow longer x-axis labels
},
'axisY': {
'labelAngle': 0
},
'legend': {
'orient': 'top',
'direction': 'horizontal',
'titleFontSize': 11,
'labelFontSize': 11
},
'title': {
'fontSize': 14,
'color': ColorPalette.TEXT,
'anchor': 'start',
'subtitleFontSize': 10,
'subtitleColor': 'gray'
},
'bar': {
'color': ColorPalette.PRIMARY
}
}
}
# Register Altair theme
try:
import altair as alt
alt.themes.register('jpmc', jpmc_altair_theme)
alt.themes.enable('jpmc')
except ImportError:
pass # Altair not installed