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