insights <- generateJourneyInsights(frame_stats)Creative Journey Storytelling
The storytelling engine is modFrames’ unique capability that transforms raw frame analytics data into marketing-ready narrative insights about an artwork’s creation process.
Purpose
The storytelling engine generates human-readable narratives that:
- Communicate the artistic process to collectors and viewers
- Provide marketing angles for artwork promotion
- Highlight unique characteristics of each artwork’s creation
- Visualize the creative journey through interactive charts
Core Functions
generateJourneyInsights()
Analyzes frame_stats data and generates structured narrative insights.
Input: 21-column frame_stats data.table from artutils::get_frame_analytics()
Output: Named list with four insight categories:
list(
creative_approach = list(
title = "...",
description = "...",
marketing_angle = "..."
),
technique_phases = list(
title = "...",
description = "...",
marketing_angle = "..."
),
complexity_benchmark = list(
title = "...",
description = "...",
marketing_angle = "..."
),
signature_moment = list(
title = "...",
description = "...",
marketing_angle = "..."
)
)plotCreativeJourney()
Creates an interactive Plotly visualization of the artwork’s color evolution.
plot <- plotCreativeJourney(frame_stats, insights)Input:
-
frame_stats: 21-column data.table -
insights: Output fromgenerateJourneyInsights()
Output: Plotly htmlwidget showing:
- Color diversity over time (main line chart)
- Phase boundaries (vertical dashed lines)
- Peak moments (annotations)
- Interactive hover tooltips
Insight Categories
1. Creative Approach
Analyzes the artist’s color strategy based on:
- Color diversity trajectory
- Early-stage vs late-stage color usage
- Palette expansion patterns
Example Output:
Title: "Bold Colorist"
Description: "The artist embraced a rich, expansive palette from the start,
introducing 847 unique colors across 312 frames."
Marketing Angle: "A vibrant exploration of color that showcases the artist's
confident approach to digital expression."
2. Technique Phases
Detects distinct creative phases using the technique_phase column:
- Phase transitions indicate shifts in working style
- Duration and frame counts per phase
- Comparative analysis of phase complexity
Example Output:
Title: "3-Phase Creative Journey"
Description: "Phase 1 (Exploration): Frames 1-47, establishing foundation.
Phase 2 (Development): Frames 48-201, building complexity.
Phase 3 (Refinement): Frames 202-312, final touches."
Marketing Angle: "A methodical creative process showing mastery of pacing."
3. Complexity Benchmark
Calculates an overall complexity score based on:
- Color count relative to frame count
- Color generation rate
- Palette change volatility
Example Output:
Title: "High Complexity"
Description: "Complexity score: 87/100. This artwork demonstrates
exceptional detail with 2.7 colors per frame on average."
Marketing Angle: "A technically demanding piece showcasing advanced skill."
4. Signature Moment
Identifies the peak creative moment using:
- Maximum
palette_change_score - Frame with highest color delta
- Most intense creative period
Example Output:
Title: "Peak at Frame 156"
Description: "The artist's signature moment occurred at frame 156,
where 47 colors were added in a single session."
Marketing Angle: "Witness the decisive moment where vision became reality."
Implementation Details
Internal Helper Functions
The storytelling engine uses several internal helpers:
analyze_color_approach()
Categorizes the artist’s color strategy:
# Returns one of:
# - "bold_colorist" (high early diversity)
# - "building_palette" (gradual expansion)
# - "focused_palette" (limited, intentional)
# - "experimental" (high variance)analyze_phases()
Processes technique_phase column to generate phase descriptions:
# Groups by technique_phase
# Calculates duration, frame ranges
# Generates narrative descriptionscalculate_complexity_score()
Computes the 0-100 complexity benchmark:
# Factors:
# - unique_colors / n_frames
# - mean(palette_change_score)
# - sd(colors_added)
# Normalizes to 0-100 scalefind_peak_moment()
Identifies the signature frame:
# Finds max(palette_change_score)
# Returns frame number and metricsVisualization Details
Color Evolution Chart
The Plotly chart shows:
-
Main Trace:
unique_colorsover frame number - Phase Boundaries: Vertical dashed lines at phase transitions
- Peak Annotation: Marker at signature moment
- Styling: Artalytics brand colors, clean axes
plotCreativeJourney <- function(frame_stats, insights) {
dt <- data.table::copy(frame_stats)
# Build base plot with color evolution
p <- plotly::plot_ly(dt, x = ~frame, y = ~unique_colors, type = "scatter", mode = "lines")
# Add phase boundaries
phase_changes <- dt[, .(start_frame = min(frame)), by = technique_phase]
for (boundary in phase_changes$start_frame[-1]) {
p <- plotly::add_trace(p, x = c(boundary, boundary), y = c(0, max_y), ...)
}
# Add peak annotation
peak_frame <- insights$signature_moment$frame
p <- plotly::add_annotations(p, x = peak_frame, y = peak_y, text = "Peak", ...)
p
}Usage in compareFramesServer
The storytelling engine is invoked once per artwork load:
compareFramesServer <- function(id, r) {
moduleServer(id, function(input, output, session) {
r_frame_stats <- reactive(req(r$appdata$artwork$frame_stats))
# Generate insights once
r_journey_insights <- reactive({
dt <- r_frame_stats()
generateJourneyInsights(dt)
})
# Render insights text
output$journey_insights <- renderUI({
insights <- r_journey_insights()
# Build UI from insights structure
})
# Render visualization
output$journey_plot <- renderPlotly({
dt <- r_frame_stats()
insights <- r_journey_insights()
plotCreativeJourney(dt, insights)
})
})
}Future Enhancements
The storytelling engine is currently stable but has planned enhancements:
Planned Features
- AI-Enhanced Narratives: Integration with LLMs for more natural language
- Comparative Insights: “More complex than 85% of artworks”
- Customizable Templates: Allow artists to choose narrative styles
- Export Options: Generate marketing copy for social media
Extension Points
To add new insight types:
- Create a new internal helper function (e.g.,
analyze_rhythm()) - Add the result to the insights list in
generateJourneyInsights() - Render in the UI with consistent card structure
- Document in this vignette
API Reference
- generateJourneyInsights() - Generate narrative insights
- plotCreativeJourney() - Create visualization
- artutils::get_frame_analytics() - Data source
Next Steps
- Architecture - Full module structure
- Integration Guide - Embedding in your app
