1
+ from __future__ import annotations
2
+
1
3
import math
2
4
from collections import Counter
3
5
from collections .abc import Callable
6
+ from pathlib import Path
4
7
5
8
from .font import FontWrapper
6
9
from .image import ImageWrapper
7
10
from .main import fill_next_word
8
11
from .rectangle import Rectangle
12
+ from .util import Color
9
13
10
14
11
15
# pylint: disable=unused-argument
12
16
def make_word_cloud (
13
17
all_words : list [str ],
14
18
width : int = 500 ,
15
19
height : int = 500 ,
16
- font_color : tuple [int , int , int ] = (255 , 255 , 0 ),
17
- background_color : tuple [int , int , int ] = (73 , 109 , 137 ),
20
+ font_path : Path | None = None ,
21
+ font_color : Color = (255 , 255 , 0 ),
22
+ font_color_func : Callable [[float ], Color ] | None = None ,
23
+ background_color : Color = (73 , 109 , 137 ),
18
24
minimum_font_size : int = 1 ,
19
25
maximum_font_size : int = 100 ,
20
26
word_padding : int = 0 , # TODO
@@ -28,24 +34,32 @@ def make_word_cloud(
28
34
assert (
29
35
0 < minimum_font_size < maximum_font_size
30
36
), "Invalid font sizes, must be positive (in pixels)"
37
+ assert (
38
+ font_color is not None or font_color_func is not None
39
+ ), "Must specify a fixed font color or function"
31
40
32
41
# Create a new image and font
42
+ font_path = font_path or FontWrapper .default_font ()
43
+ font_color_func = font_color_func or (lambda _ : font_color )
33
44
image = ImageWrapper (width , height , background_color )
34
- font = FontWrapper (color = font_color , size = maximum_font_size )
45
+ font = FontWrapper (
46
+ path = font_path , color_func = font_color_func , size = maximum_font_size
47
+ )
35
48
36
49
# Handle data
37
50
word_counts = Counter (all_words )
38
51
_ , first_count = word_counts .most_common (1 )[0 ]
39
52
40
53
available_rectangles = [Rectangle (width = width , height = height , x = 0 , y = 0 )]
41
54
for word , count in word_counts .most_common ():
42
- required_font_size = maximum_font_size * scaling_func (count / first_count )
55
+ frequency = count / first_count
56
+ required_font_size = maximum_font_size * scaling_func (frequency )
43
57
44
58
if required_font_size < minimum_font_size :
45
59
break
46
60
47
61
available_rectangles = fill_next_word (
48
- word , available_rectangles , image , font [required_font_size ]
62
+ word , available_rectangles , image , font [required_font_size ], frequency
49
63
)
50
64
51
65
return image .img
0 commit comments