logo in word cloud

This commit is contained in:
2025-12-16 17:44:50 -08:00
parent 228a6daa59
commit 4ba8af03d2

View File

@@ -194,13 +194,13 @@ def _():
# Start with loading all necessary libraries # Start with loading all necessary libraries
import numpy as np import numpy as np
from os import path from os import path
from PIL import Image from PIL import Image, ImageDraw
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import warnings import warnings
warnings.filterwarnings("ignore") warnings.filterwarnings("ignore")
return Image, WordCloud, np, plt return Image, ImageDraw, WordCloud, np, plt
@app.cell @app.cell
@@ -222,11 +222,23 @@ def _(df):
# create list of keywords sorted by their frequencies. only store the keyword # create list of keywords sorted by their frequencies. only store the keyword
sorted_keywords = sorted(keyword_freq_filtered.items(), key=lambda x: x[1], reverse=True) sorted_keywords = sorted(keyword_freq_filtered.items(), key=lambda x: x[1], reverse=True)
sorted_keywords_list = [kw for kw, freq in sorted_keywords] sorted_keywords_list = [f"{kw}:{freq}" for kw, freq in sorted_keywords]
sorted_keywords_list sorted_keywords_list
return (keyword_freq_filtered,) return (keyword_freq_filtered,)
@app.cell
def _():
IGNORE_WORDS = {
'chase as a brand': [
"brand"
]
}
return (IGNORE_WORDS,)
@app.cell @app.cell
def _(plt): def _(plt):
import random import random
@@ -248,37 +260,137 @@ def _(plt):
@app.cell @app.cell
def _(Image, np): def _():
chase_mask = np.array(Image.open("./data/assets/Chase-National-Bank-Logo.png")) # chase_mask = np.array(Image.open("./data/assets/Chase-National-Bank-Logo.png"))
def transform_format(val): # def transform_format(val):
if val == 0: # if val == 0:
return 255 # return 255
else: # else:
return 1 # return 1
transformed_chase_mask = np.ndarray((chase_mask.shape[0], chase_mask.shape[1]), np.int32) # transformed_chase_mask = np.ndarray((chase_mask.shape[0], chase_mask.shape[1]), np.int32)
for i in range(len(chase_mask)): # for i in range(len(chase_mask)):
transformed_chase_mask[i] = list(map(transform_format, chase_mask[i])) # transformed_chase_mask[i] = list(map(transform_format, chase_mask[i]))
return return
@app.cell @app.cell
def _(WordCloud, blue_color_func, keyword_freq_filtered, mo, plt): def _(mo):
wordcloud = WordCloud( buffer = -100 # Adjust this to increase/decrease space between logo and words
background_color='white', canvas_size = (1200, 800)
width=800,
max_font_size=60, logo_switch = mo.ui.switch(label="Include Chase Logo", value=False)
max_words=20, logo_switch
# colormap='Blues',
# relative_scaling=0.5, # Use rank in sorted frequency list instead of pure frequency return buffer, canvas_size, logo_switch
color_func=blue_color_func,
# mask=chase_mask
# random_state=42 @app.cell(hide_code=True)
).generate_from_frequencies(keyword_freq_filtered) def _(
IGNORE_WORDS,
Image,
ImageDraw,
WordCloud,
blue_color_func,
buffer,
canvas_size,
keyword_freq_filtered,
logo_switch,
mo,
np,
plt,
tag_select,
):
# remove specific keywords depending on selected tag
if IGNORE_WORDS.get(tag_select.value.lower()):
for word in IGNORE_WORDS[tag_select.value.lower()]:
if word in keyword_freq_filtered:
del keyword_freq_filtered[word]
if logo_switch.value:
# 1. Load the logo
# Make sure this path points to your uploaded file
logo_path = "./data/assets/JP-Morgan-Chase-Symbol.png"
logo = Image.open(logo_path).convert("RGBA")
# Optional: Resize logo if it's too large or small for the canvas
# target_width = 600
# ratio = target_width / logo.width
# logo = logo.resize((target_width, int(logo.height * ratio)), Image.Resampling.LANCZOS)
target_width = 600 # Set a reasonable size for the logo
if logo.width > target_width:
ratio = target_width / logo.width
new_height = int(logo.height * ratio)
# Use Image.Resampling.LANCZOS for high-quality downsampling
# If you get an error, try Image.LANCZOS or Image.ANTIALIAS
logo = logo.resize((target_width, new_height), Image.Resampling.LANCZOS)
# 3. Create the mask (0 = draw here, 255 = don't draw here)
# Initialize with 0 (black/draw everywhere)
mask_image = Image.new("L", canvas_size, 0)
draw = ImageDraw.Draw(mask_image)
# 4. Draw a protected circular area in the center
center = (canvas_size[0] // 2, canvas_size[1] // 2)
# Calculate radius: half of logo max dimension + buffer
radius = (max(logo.size) // 2) + buffer
# Draw the white circle (255) which the WordCloud will avoid
draw.ellipse(
(center[0] - radius, center[1] - radius, center[0] + radius, center[1] + radius),
fill=255
)
chase_mask = np.array(mask_image)
# Generate the WordCloud
wordcloud = WordCloud(
background_color='white',
width=canvas_size[0],
height=canvas_size[1],
max_font_size=100, # Increased font size for larger canvas
max_words=20, # Increased word count to fill space
color_func=blue_color_func,
mask=chase_mask, # Apply the circular mask
contour_width=0,
contour_color='steelblue'
).generate_from_frequencies(keyword_freq_filtered)
else:
# Generate the WordCloud
wordcloud = WordCloud(
background_color='white',
width=canvas_size[0],
height=canvas_size[1],
max_font_size=100, # Increased font size for larger canvas
max_words=20, # Increased word count to fill space
color_func=blue_color_func,
# mask=chase_mask, # Apply the circular mask
# contour_width=0,
# contour_color='steelblue'
).generate_from_frequencies(keyword_freq_filtered)
# Convert WordCloud to Image to composite the logo
wc_image = wordcloud.to_image()
if logo_switch.value:
# Calculate position to center the logo
logo_pos = (
(canvas_size[0] - logo.width) // 2,
(canvas_size[1] - logo.height) // 2
)
# Paste logo (using alpha channel as mask to keep transparency)
wc_image.paste(logo, logo_pos, logo)
# Display the generated image
fig = plt.figure(figsize=(7,7))
# Display the generated image: # Display the generated image:
plt.imshow(wordcloud, interpolation='bilinear') plt.imshow(wc_image, interpolation='bilinear')
plt.axis("off") plt.axis("off")
plt.show() plt.show()
@@ -289,11 +401,11 @@ def _(WordCloud, blue_color_func, keyword_freq_filtered, mo, plt):
on_click=lambda val: True on_click=lambda val: True
) )
save_wordcloud_btn save_wordcloud_btn
return save_wordcloud_btn, wordcloud return save_wordcloud_btn, wc_image
@app.cell @app.cell
def _(WORKING_DIR, mo, save_wordcloud_btn, tag_select, wordcloud): def _(WORKING_DIR, mo, save_wordcloud_btn, tag_select, wc_image):
# Wait for start processing button # Wait for start processing button
mo.stop(not save_wordcloud_btn.value, "Click button above to save wordcloud image") mo.stop(not save_wordcloud_btn.value, "Click button above to save wordcloud image")
@@ -315,7 +427,7 @@ def _(WORKING_DIR, mo, save_wordcloud_btn, tag_select, wordcloud):
next_number = 1 next_number = 1
fpath = WORKING_DIR / f'wordcloud_{tag_select.value.replace(" ", "-")}_{next_number}.png' fpath = WORKING_DIR / f'wordcloud_{tag_select.value.replace(" ", "-")}_{next_number}.png'
wordcloud.to_file(fpath) wc_image.save(fpath)
mo.md(f"Wordcloud saved to: {fpath}") mo.md(f"Wordcloud saved to: {fpath}")
return return