og traits

This commit is contained in:
2026-02-02 18:37:45 +01:00
parent a62524c6e4
commit 29df6a4bd9
3 changed files with 101 additions and 0 deletions

View File

@@ -1039,3 +1039,65 @@ class QualtricsPlotsMixin:
print(f"Word cloud saved to: {filepath}")
return fig
def plot_character_trait_frequency(
self,
data: pl.LazyFrame | pl.DataFrame | None = None,
title: str = "Trait Frequency per Brand Character",
x_label: str = "Trait",
y_label: str = "Frequency (Times Chosen)",
height: int | None = None,
width: int | str | None = None,
) -> alt.Chart:
"""Create a grouped bar plot showing how often each trait is chosen per character.
Original request: "I need a bar plot that shows the frequency of the times
each trait is chosen per brand character"
Expects data with columns: Character, Trait, Count (as produced by
transform_character_trait_frequency).
"""
df = self._ensure_dataframe(data)
# Ensure we have the expected columns
required_cols = {'Character', 'Trait', 'Count'}
if not required_cols.issubset(set(df.columns)):
return alt.Chart(pd.DataFrame({'text': ['Data must have Character, Trait, Count columns']})).mark_text().encode(text='text:N')
# Convert to pandas for Altair
plot_df = df.to_pandas() if hasattr(df, 'to_pandas') else df
# Calculate total per trait for sorting (traits with highest overall frequency first)
trait_totals = plot_df.groupby('Trait')['Count'].sum().sort_values(ascending=False)
trait_order = trait_totals.index.tolist()
# Get unique characters for color mapping
characters = plot_df['Character'].unique().tolist()
# Interactive legend selection - click to filter
selection = alt.selection_point(fields=['Character'], bind='legend')
chart = alt.Chart(plot_df).mark_bar().encode(
x=alt.X('Trait:N',
title=x_label,
sort=trait_order,
axis=alt.Axis(labelAngle=-45, labelLimit=200)),
y=alt.Y('Count:Q', title=y_label),
xOffset='Character:N',
color=alt.Color('Character:N',
scale=alt.Scale(domain=characters,
range=ColorPalette.CATEGORICAL[:len(characters)]),
legend=alt.Legend(orient='top', direction='horizontal', title='Character')),
opacity=alt.condition(selection, alt.value(1), alt.value(0.2)),
tooltip=[
alt.Tooltip('Character:N', title='Character'),
alt.Tooltip('Trait:N', title='Trait'),
alt.Tooltip('Count:Q', title='Frequency')
]
).add_params(selection).properties(
title=self._process_title(title),
width=width or 900,
height=height or getattr(self, 'plot_height', 400)
)
chart = self._save_plot(chart, title)
return chart

38
reference.py Normal file
View File

@@ -0,0 +1,38 @@
ORIGINAL_CHARACTER_TRAITS = {
"the_familiar_friend": [
"Warm",
"Friendly",
"Approachable",
"Familiar",
"Casual",
"Appreciative",
"Benevolent",
],
"the_coach": [
"Empowering",
"Encouraging",
"Caring",
"Positive",
"Optimistic",
"Guiding",
"Reassuring",
],
"the_personal_assistant": [
"Forward-thinking",
"Progressive",
"Cooperative",
"Intentional",
"Resourceful",
"Attentive",
"Adaptive",
],
"the_bank_teller": [
"Patient",
"Grounded",
"Down-to-earth",
"Stable",
"Formal",
"Balanced",
"Efficient",
]
}

View File

@@ -1073,6 +1073,7 @@ class QualtricsSurvey(QualtricsPlotsMixin):
return self._get_subset(q, QIDs, rename_cols=True), None
def process_speaking_style_data(
df: Union[pl.LazyFrame, pl.DataFrame],
trait_map: dict[str, str]