logo in word cloud
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user