This application provides a brief background on and visualizes data from all of the episodes of the TV show Friends and allows users to answer the following questions:
Who are the most important characters?
How much do the major characters speak?
What do characters say?
Who appears in scenes together?
Where do characters speak?
Within the application, we have a visualization dedicated to answering each one of these questions. However, users may also come up with their own questions and answer them by exploring the data displayed in the multiple visualizations.
This application can be used by anyone, regardless of their knowledge of Friends. We have included a brief background at the top of the application so that users with limited knowledge can better understand the data displayed.
The original transcript data was a .txt file downloaded from Kaggle. For each episode of Friends, it contains the name of that episode, the credits, a description of each scene, and each line spoken in that scene, along with who said it. Unfortunately, the format of the data for each episode was not exactly the same, as there were different transcribers. However, we were able to process the data into a usable format, as described in the following section.
As previously mentioned, the original data was in a .txt file with variable formatting. To resolve this, regular expressions were used to search and replace/delete content throughout the file. Once the .txt file was in a suitable format, a function (in js/createJSONFile.js) was created to read in that .txt file and output a .json file with the following schema. That function was run once, and the generated .json file was used instead of the .txt file thereafter.
{
seasons: [
{
number: number,
episodes: [
{
number: number,
name: string,
scenes: [
{
number: number,
location: string
lines: [
{
character: string,
spokenLine: string,
words: [string, ...]
},
...
]
},
...
]
},
...
]
},
...
]
}
Every time the app is run, the JSON file is read in and a variable (called allData) is initialized. This allData variable is used throughout the application to determine the data needed for each visualization. Within main.js the methods in helperMethods.js are called when the app starts and whenever a visualization's option is selected. These methods were created specifically to retrieve the necessary properties and values of allData for a given visualization and to output a variable that is in a suitable format for that visualization.
Different data is displayed within each visualization, as explained below. However, in general, only named characters were included in the visualizations' data. We made this decision, as we felt that the data about recognizable characters would be more interesting and advantageous to the user than that of characters who are not meant to be as impactful. We also limited selection options to the entire show or a specific season, rather than a specific episode, as we want to encourage the user to uncover overall trends.
The bar chart visualizes the most prominent characters throughout the show based on either the number of episodes they appear in or the number of lines they deliver. The chart allows the user to select specific seasons or the entire show, along with a selector to toggle between counting appearances or lines spoken. The bars are all different bright colors. We start with red, yellow, and blue for the first three bars to match the color of the dots in the Friends logo. Then the rest of the bars are different colors to keep the application very colorful and not just red, yellow, and blue.
The data is organized to provide insights into the top 10 characters for the selected time period. The data is organized in an array of objects that is updated based on the selected parameters.
The format of the objects is similar for both the number of episodes and the number of lines. For example, when counting episodes, the object will include the character's name and the total number of episodes they were in:
{
character: "Ross",
numAppearances: 22
}
For the number of lines, similarly, the object contains the character's name and the total lines they delivered:
{
character: "Rachel",
numLines: 9265
}
The y-axis is dynamic and updates based on the numAppearances or numLines values for the 10 characters being displayed. The x-axis is also dynamic and updates the characters being displayed so it is always the top 10 characters in the selected categories and orders them from highest to lowest.
The user can interact with the visualization by not only selecting values to filter the data but also hovering over the bars and a tooltip appears displaying the character's name and the number of lines they spoke or number of episodes they were in.
The heat map shows the quantity of spoken dialogue by the six main characters within each episode throughout the entirety of Friends. By utilizing a selector, users can navigate through the dialogue contributions of each character on an episode-by-episode and season-by-season basis. The heat map adapts to visualize these dynamics, with its colors varying to signify the frequency of the character's lines, which ultimately shows a visual representation of their prominence within each episode.
The interactive feature of this visualization is a dropdown menu that enables the selection of one of the six main characters. The heat map's display is responsive to the chosen character, showcasing data pertaining to that individual. Each new selection not only updates the data represented but shifts the color scheme associated with the character.
The heat map's color palette is intentionally chosen for its vibrancy and the ability to stand out, which maintains the overall appeal of the application. It uses the bright colors found in the Friends logo, with the first three colors directly referencing the logo’s iconic red, yellow, and blue. The subsequent colors—green, light tan, and purple—mirror the colors used in the other visualizations.
The data used for the heat map is comprised of an array of objects. Each object represents a data point that correlates to a cell on the grid, which includes the season and episode number to organize the x and y axes respectively, the episode title for tooltip information, and the number of lines spoken by the character, which is visually represented as the cell's color intensity. A sample data object is below:
{
seasonNum: 1,
episodeNum: 1,
episodeName: "The One Where It All Began",
linesSpoken: 39
}
The axes remain constant regardless of the user's interaction. The x-axis represents the range of episodes, while the y-axis denotes the sequence of seasons.
The user can hover over any cell of the heat map to display additional information, including the episode title and the specific count of lines spoken, thereby enriching the user experience beyond the episode and season number.
The word cloud visualizes the most frequently spoken words by characters. The user can filter the words shown by selecting specific seasons of the entire series and selecting the character they would like to see. The words are all either red, yellow, or blue to match the dots in the Friends logo. They are randomly assigned a color; the colors do not correlate with the data.
The data is structured to show the most prominent words spoken by the character in the chosen season. It is organized in a dynamic array of objects that updates based on the selected character and season. Each object contains a word and the count, for example:
{
word: "oh",
count: 687
},
{
word: "hey",
count: 589
},
...
The array contains objects for the top 50 words spoken by the character selected in the selected season. Common words like "I", "a", "and", etc. are filtered out and not included in this visualization. The size of the word in the word cloud is based on the count so the higher the count, the larger the word will be.
The user can also interact with the visualization by hovering over a word and a tooltip will appear displaying the word and the count.
The arc diagram shows the network of interactions between the characters across various episodes of the show. Users can explore these relationships by season by using the dropdown menu. The diagram responds to a new selection by reflecting the interactions specific to the selected timeframe and updating the arcs between all 10 characters, which vary in thickness to represent the volume of shared scenes. With each new season picked, not only is the data updated, but the colors of the arcs also shift to match the consistent colors in the application.
The color of the arcs across each season is chosen deliberately to align with the other colors used in the other visualizations. The first three colors—red, yellow, and blue—are derived from the logo itself. While the other colors were chosen to remain distinct and vibrant and match the color palette chosen for the entire application.
The data used for the arc diagram is an array of objects, where each object details the interactions between two characters. The object includes identifiers for the characters involved and a numerical value representing the count of their interactions. A sample data object is below:
{
characterA: "Joey",
characterB: "Monica",
interactions: 111
}
This dataset is designed to update based on the season chosen from the dropdown, where the nodes of the six main characters are on the left and four side characters are on the right. The four side characters are chosen depending on the season and the weight of the line between characters is directly proportional to their interaction count.
Users can engage with the arc diagram by hovering over a character name. It results in that character’s interaction arcs remaining opaque colored while others fade transparently. The tooltip, appearing upon hover, adds to this interaction by listing the exact number of scenes each main character shares with others, ordered from most to least frequent interactions.
The tree map visualizes the frequency of scenes (locations) and, within those locations, the frequency of the 10 major characters' appearances.
The data is structured to have the most frequent locations and associated frequency of characters. A snippet of the data object is below:
{
name: "Locations",
children: [
{
name: "Central Perk",
children: [
{
name: "Phoebe",
value: 358
},
{
name: "Ross",
value: 310
},
{
name: "Chandler",
value: 297
},
...
]
},
...
]
}
This structure holds the 10 locations in order of frequency and each of those locations holds the 10 characters in order of number of appearances.
The user can interact with this visualization by hovering over certain boxes. When this is done, the user will see the location, the character, and the number of appearances of that character.
Within our sketch of the overall layout, we thought it would be best to have the information about the show across the top, with a 2x2 grid of visualizations and then the arc diagram below.
The title, author list, and Friends logo were kept consistent with the sketch.
After implementing the visualizations, it was discovered that this layout would not work. The tree map, bar chart, and word cloud could be included in the grid, however, the heatmap was too wide. To remedy this, the implemented layout is different from our initial sketch. The show description is placed next to the tree map at the top. Then, the arc diagram is below that, taking up the entire width. After that, the bar chart and the word cloud are side-by-side. Finally, the heat map takes up the width of the screen.
In the initial sketch of the bar chart, we have two dropdown boxes that allow the user to select what season they would like the chart to display and whether the data will be based on the number of lines the character spoke during the episode or the number of episodes they appeared in. In the actual bar chart we implemented, we kept the season dropdown but instead of a dropdown for Episodes or Lines, we decided since there are only two options, it would make more sense as a two-item selector where the user just clicks on episodes or lines.
Our sketch also has the bars in a random order. We designed it like this because it is typical for bars in a bar chart to be in a varied order. However, in our application, we decided to order the bars in order of tallest to shortest. This is because the bars for the six main characters are so much bigger than the secondary characters in every season, for both categories, the smaller bars would be overshadowed in between two taller bars.
The color of the bars in our initial sketches are all different colors and the first three colors are red, yellow, and blue, which are the colors of the dots in the show's logo. The other colors are different colors which is how we kept it in the implemented visualization because the show is a fun and bright show so we thought it would be appropriate to have lots of different bright, happy colors throughout our application.
In the initial sketch of the heat map there is a "Character Select Dropdown" to choose among the six main characters. Within the development process, we kept the character selection feature as it provides a simple method for users to filter the data by character. As illustrated in the sketch and carried onto the final visualization, the color intensity of each cell was dependent on the number of lines spoken in any given episode or season.
Also carried onto the final visualization, the color intensity of each cell is dependent on the number of lines spoken in any given episode or season. The color chosen in the sketch was one of the colors chosen in the final visualization, however, other vibrant and distinct colors were chosen for the other characters.
For the initial sketch of the word cloud, we have a season dropdown so the user can select what season they wish to view. We do not yet have the character dropdown in the initial sketch because we initially were going to be visualizing one character's words. The words are all black for simplicity but we ended up adding color to the words in the implemented visualization to match the colors of the dots in the Friends logo.
The sketch also has differing sizes of the words where the larger the word, the more it was spoken. This sizing aspect was used in our application since we found it to be an intuitive way to visually represent the differing frequencies of each word.
Another aspect of the sketch is that we rotated some of the words by 90 degrees. We ultimately did not implement this part and kept all the words horizontal to increase readability.
In the sketch for the arc diagram, there is a "Season Select Dropdown" for choosing the specific season of interest, which was kept in the final visualization.
Initially, characters were represented by colored dots along a horizontal axis, with black, opaque lines arching between them to represent interactions. However, in our final visualization, we opted for a more streamlined design by using only the characters' names without separate node markers.
For the arcs themselves, while the sketch showed a uniform black color for all arcs, the final visualization uses a distinct color scheme. The arc colors change according to the season selected which corresponds to the color palette used in the application.
The color selection for the tree map is to have a different color based on location instead of by character since the main question to be answered by this visualization is "Where do characters speak?" and not just a certain character.
Another thing that had to be determined was if we wanted to have titles on each location section. We decided against this as we have the tooltips to view the information within the visual as adding titles made boxes even smaller and harder to view with text that was getting very small to fit near the certain box.
A user of our application can arrive at a variety of discoveries. See below for some examples:
The six main characters are significantly more relevant or important than any of the minor characters.
The bar chart shows that all six main characters appeared in all 227 episodes and the next character appearing in the most episodes was Gunther in only 49 episodes of the entire show. Then, after Gunther was Mike, who appeared in only 16 episodes.
While Gunther appears in more episodes than any other non-main character, he never is in the top 10 characters that spoke the most lines in any season.
This makes sense to viewers, as Gunther is a character that is often working in the background when the main characters are at Central Perk and he often only speaks a line or two the entire episode.
Phoebe appears and speaks in Central Perk 358 times throughout the series, while Monica appears and speaks there 257 times (101 fewer times than Phoebe).
This could be explained by Monica's apartment being the most prominent location throughout the series while Phoebe's apartment is not a prominent location.
Starting in season 5 and continuing for the rest of the show, Monica and Chandler have more scenes with each other than they do with any other character (season 5 is when they begin a relationship).
Season 9 has the most prominent differences as they have 101 scenes together and their second most scenes with a character include Monica having 61 scenes with Phoebe and Chandler having 55 with Joey.
D3 was used to handle the complex data-driven visualizations. It dynamically creates and updates the five visualizations according to the dataset, allowing for interactive selection and detailed display of the data. The d3.layout.cloud npm package, in particular, was used to create the word cloud.
The createJSONFile.js can be run to create a JSON version of the data from the Friends_Transcript.txt file content. This was only run once, and then the JSON data is what's loaded every time the app starts up.
The helperMethods.js file contains all of the logic used to retrieve and format the data needed for each visualization. Additionally, the helperVariables.js file contains variables that are used within those methods.
The main.js file serves as the central hub of the program, it handles the initialization and interactions of the different visualizations. It's where the JSON data is loaded and parsed to be passed on to other components.
The files within js/visualizations each define a JavaScript class responsible for creating and updating a specific visualization. These classes contain all the methods needed for setting up SVG elements, binding data, and rendering the visuals based on user interaction.
The style.css file contains custom styles that define the overall look and layout of the application, including titles and tooltips.
The index.html file sets up a straightforward framework for the application, arranging div elements for each data visualization—map, timeline, pie chart, bar chart, heatmap, and radar chart. It includes an interactive search section and placeholders for user interaction controls. The document references the visualization JavaScript files for functionality and CSS files for styling.
The code for the application can be accessed on a public GitHub repository. Instructions to download and run the application locally can be found in the README.md file. The application is deployed online using Netlify, and can be accessed here: https://data-vis-project-3.netlify.app/.
Initial sketching
Word cloud implementation
Bar chart implementation
About section
Documentation
Tree map implementation
Documentation
Data processing
Selection interactions and data updates
Overall layout implementation
Documentation
Initial sketching
Heat map implementation
Arc diagram implementation
Documentation
Artificial intelligence (ChatGPT, in particular) was used to help with the data processing and manipulation. The original Friends_Transcript.txt file did not have an entirely consistent format, so AI was used to determine various regular expressions to find and replace data as needed. Additionally, collecting and formatting the data from the JSON file in a way that was needed for each visualization was highly complex. ChatGPT was used to generate the methods within helperMethods.js, which takes all of the JSON data and converts it into an object formatted specifically for a given visualization.
For the most part, the use of generative AI worked well. However, there were times when questions needed to be rephrased or more information needed to be provided to the agent. Thorough testing on the methods generated by the model was completed to ensure that the output was what was requested.