import matplotlib.pyplot as plt
from pythonosc import udp_client
# Paths to the emotion mapping file and input text file
mapping_file_path = 'C:/Users/Chris/PycharmProjects/SentimentAnalysis_Test/emotions.txt'
input_text_file_path = 'C:/Users/Chris/PycharmProjects/SentimentAnalysis_Test/read.txt'
categories = ['angel', 'hero', 'feminist', 'rebel']
# Color mapping for categories
color_mapping = {'angel': 'yellow', 'hero': 'darkblue', 'feminist': 'green', 'rebel': 'red'}
# Variable to track the previous text
# Variable to store the last distribution
# Variable to track the number of new messages
osc_client = udp_client.SimpleUDPClient("127.0.0.1", 9000)
# Function to load emotion mappings from a file
def load_emotion_mapping(file_path):
with open(file_path, 'r') as f:
parts = line.strip().split(':')
mapping[word.strip().lower()] = category.strip().lower()
# Function to load the input text from a file
def load_input_text(file_path):
with open(file_path, 'r') as f:
# Function to process the text and count emotions per category
def count_emotions(text, mapping, categories):
# Remove punctuation from text
text = text.translate(str.maketrans('', '', string.punctuation))
text_words = text.lower().split()
counts = {category: 0 for category in categories}
matched_words = {category: [] for category in categories}
matched_words[category].append(word)
return counts, matched, matched_words
# Random distribution generator
def generate_random_distribution(categories):
random_distribution = np.random.dirichlet(np.ones(len(categories)), size=1)[0]
return {categories[i]: random_distribution[i] * 100 for i in range(len(categories))}
# Plotting function with adjusted annotation position
def plot_emotion_distribution(counts, categories, no_matches, matched_words):
plt.clf() # Clear the previous plot
values = [counts.get(category, 0) for category in categories]
colors = [color_mapping[category] for category in categories] # Assigning colors based on category
plt.bar(categories, values, color=colors) # Using assigned colors
plt.xlabel('Emotion Category')
plt.title('Emotion Distribution')
plt.ylim(0, max(values) + 20 + 2*max(len(words) for words in matched_words.values())) # Provide extra vertical space above bars
# Add the annotation for no matches if randomly generated
plt.text(len(categories) / 2, max(values) + 10, '0% Match. Generating Random Distribution.', fontsize=10,
color='red', ha='center')
# Add matched words above each column
for i, category in enumerate(categories):
words = matched_words[category]
for j, word in enumerate(words):
plt.text(i, values[i] + 2 + j * 2, word, fontsize=8, color='black', ha='center') # Increased spacing
plt.pause(0.1) # Pause to update the plot
# Function to send the emotion distribution and matched words via OSC
def send_osc(counts, matched_words, new_message_count):
for category, value in counts.items():
osc_client.send_message(f"/{category}", value)
words_message = ', '.join(matched_words[category])
osc_client.send_message(f"/{category}_words", words_message if words_message else " ")
osc_client.send_message("/new_message", new_message_count)
# Load the emotion mapping from the file
emotion_mapping = load_emotion_mapping(mapping_file_path)
# Load the input text from the file
text = load_input_text(input_text_file_path)
# Check if the text has changed
text_changed = text != previous_text
# Increment new message counter if text has changed
# Check and count emotions
counts, matched, matched_words = count_emotions(text, emotion_mapping, categories)
# If there are no matched words
# Generate random distribution only if the text has changed or there is no previous random distribution
if text_changed or last_distribution is None:
last_distribution = generate_random_distribution(categories)
print("Emotion Distribution (Random Generation):")
for category, value in last_distribution.items():
print(f"{category}: {value:.2f}%")
plot_emotion_distribution(last_distribution, categories, True, matched_words)
send_osc(last_distribution, matched_words, new_message_count)
# Re-use the last random distribution if the text hasn't changed
print("Emotion Distribution (Re-using Random Generation):")
for category, value in last_distribution.items():
print(f"{category}: {value:.2f}%")
plot_emotion_distribution(last_distribution, categories, True, matched_words)
send_osc(last_distribution, matched_words, new_message_count)
# Normalize percentages if words matched
total_count = sum(counts.values())
counts = {k: (v / total_count) * 100 for k, v in counts.items()}
print("Emotion Distribution:")
for category, value in counts.items():
print(f"{category}: {value:.2f}%")
plot_emotion_distribution(counts, categories, False, matched_words)
send_osc(counts, matched_words, new_message_count)
last_distribution = counts
# Update the previous text to the current text
time.sleep(1) # Wait for 1 second before repeating