<s> import warnings <EOL> from random import Random <EOL> import os <EOL> import re <EOL> import sys <EOL> import colorsys <EOL> import numpy as np <EOL> from operator import itemgetter <EOL> from PIL import Image <EOL> from PIL import ImageColor <EOL> from PIL import ImageDraw <EOL> from PIL import ImageFont <EOL> from . query_integral_image import query_integral_image <EOL> item1 = itemgetter ( <NUM_LIT:1> ) <EOL> FONT_PATH = os . environ . get ( "<STR_LIT>" , os . path . join ( os . path . dirname ( __file__ ) , <EOL> "<STR_LIT>" ) ) <EOL> STOPWORDS = set ( [ x . strip ( ) for x in open ( os . path . join ( os . path . dirname ( __file__ ) , <EOL> '<STR_LIT>' ) ) . read ( ) . split ( '<STR_LIT:\n>' ) ] ) <EOL> class IntegralOccupancyMap ( object ) : <EOL> def __init__ ( self , height , width , mask ) : <EOL> self . height = height <EOL> self . width = width <EOL> if mask is not None : <EOL> self . integral = np . cumsum ( np . cumsum ( <NUM_LIT:255> * mask , axis = <NUM_LIT:1> ) , <EOL> axis = <NUM_LIT:0> ) . astype ( np . uint32 ) <EOL> else : <EOL> self . integral = np . zeros ( ( height , width ) , dtype = np . uint32 ) <EOL> def sample_position ( self , size_x , size_y , random_state ) : <EOL> return query_integral_image ( self . integral , size_x , size_y , random_state ) <EOL> def update ( self , img_array , pos_x , pos_y ) : <EOL> partial_integral = np . cumsum ( np . cumsum ( img_array [ pos_x : , pos_y : ] , axis = <NUM_LIT:1> ) , <EOL> axis = <NUM_LIT:0> ) <EOL> if pos_x > <NUM_LIT:0> : <EOL> if pos_y > <NUM_LIT:0> : <EOL> partial_integral += ( self . integral [ pos_x - <NUM_LIT:1> , pos_y : ] <EOL> - self . integral [ pos_x - <NUM_LIT:1> , pos_y - <NUM_LIT:1> ] ) <EOL> else : <EOL> partial_integral += self . integral [ pos_x - <NUM_LIT:1> , pos_y : ] <EOL> if pos_y > <NUM_LIT:0> : <EOL> partial_integral += self . integral [ pos_x : , pos_y - <NUM_LIT:1> ] [ : , np . newaxis ] <EOL> self . integral [ pos_x : , pos_y : ] = partial_integral <EOL> def random_color_func ( word = None , font_size = None , position = None , <EOL> orientation = None , font_path = None , random_state = None ) : <EOL> """<STR_LIT>""" <EOL> if random_state is None : <EOL> random_state = Random ( ) <EOL> return "<STR_LIT>" % random_state . randint ( <NUM_LIT:0> , <NUM_LIT:255> ) <EOL> def get_single_color_func ( color ) : <EOL> """<STR_LIT>""" <EOL> old_r , old_g , old_b = ImageColor . getrgb ( color ) <EOL> rgb_max = <NUM_LIT> <EOL> h , s , v = colorsys . rgb_to_hsv ( old_r / rgb_max , old_g / rgb_max , old_b / rgb_max ) <EOL> def single_color_func ( word = None , font_size = None , position = None , <EOL> orientation = None , font_path = None , random_state = None ) : <EOL> """<STR_LIT>""" <EOL> if random_state is None : <EOL> random_state = Random ( ) <EOL> r , g , b = colorsys . hsv_to_rgb ( h , s , random_state . uniform ( <NUM_LIT> , <NUM_LIT:1> ) ) <EOL> return '<STR_LIT>' . format ( r * rgb_max , g * rgb_max , b * rgb_max ) <EOL> return single_color_func <EOL> class WordCloud ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , font_path = None , width = <NUM_LIT> , height = <NUM_LIT:200> , margin = <NUM_LIT:2> , <EOL> ranks_only = None , prefer_horizontal = <NUM_LIT> , mask = None , scale = <NUM_LIT:1> , <EOL> color_func = random_color_func , max_words = <NUM_LIT:200> , min_font_size = <NUM_LIT:4> , <EOL> stopwords = None , random_state = None , background_color = '<STR_LIT>' , <EOL> max_font_size = None , font_step = <NUM_LIT:1> , mode = "<STR_LIT>" , relative_scaling = <NUM_LIT:0> , regexp = None ) : <EOL> if font_path is None : <EOL> font_path = FONT_PATH <EOL> self . font_path = font_path <EOL> self . width = width <EOL> self . height = height <EOL> self . margin = margin <EOL> self . prefer_horizontal = prefer_horizontal <EOL> self . mask = mask <EOL> self . scale = scale <EOL> self . color_func = color_func <EOL> self . max_words = max_words <EOL> self . stopwords = stopwords or STOPWORDS <EOL> self . min_font_size = min_font_size <EOL> self . font_step = font_step <EOL> self . regexp = regexp <EOL> if isinstance ( random_state , int ) : <EOL> random_state = Random ( random_state ) <EOL> self . random_state = random_state <EOL> self . background_color = background_color <EOL> if max_font_size is None : <EOL> max_font_size = height <EOL> self . max_font_size = max_font_size <EOL> self . mode = mode <EOL> if relative_scaling < <NUM_LIT:0> or relative_scaling > <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" <EOL> % relative_scaling ) <EOL> self . relative_scaling = relative_scaling <EOL> if ranks_only is not None : <EOL> warnings . warn ( "<STR_LIT>" <EOL> "<STR_LIT>" , DeprecationWarning ) <EOL> def fit_words ( self , frequencies ) : <EOL> """<STR_LIT>""" <EOL> return self . generate_from_frequencies ( frequencies ) <EOL> def generate_from_frequencies ( self , frequencies ) : <EOL> """<STR_LIT>""" <EOL> frequencies = sorted ( frequencies , key = item1 , reverse = True ) <EOL> frequencies = frequencies [ : self . max_words ] <EOL> max_frequency = float ( frequencies [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] ) <EOL> frequencies = [ ( word , freq / max_frequency ) for word , freq in frequencies ] <EOL> self . words_ = frequencies <EOL> if self . random_state is not None : <EOL> random_state = self . random_state <EOL> else : <EOL> random_state = Random ( ) <EOL> if len ( frequencies ) <= <NUM_LIT:0> : <EOL> print ( "<STR_LIT>" <EOL> % len ( frequencies ) ) <EOL> if self . mask is not None : <EOL> mask = self . mask <EOL> width = mask . shape [ <NUM_LIT:1> ] <EOL> height = mask . shape [ <NUM_LIT:0> ] <EOL> if mask . dtype . kind == '<STR_LIT:f>' : <EOL> warnings . warn ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if mask . ndim == <NUM_LIT:2> : <EOL> boolean_mask = mask == <NUM_LIT:255> <EOL> elif mask . ndim == <NUM_LIT:3> : <EOL> boolean_mask = np . all ( mask [ : , : , : <NUM_LIT:3> ] == <NUM_LIT:255> , axis = - <NUM_LIT:1> ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % str ( mask . shape ) ) <EOL> else : <EOL> boolean_mask = None <EOL> height , width = self . height , self . width <EOL> occupancy = IntegralOccupancyMap ( height , width , boolean_mask ) <EOL> img_grey = Image . new ( "<STR_LIT:L>" , ( width , height ) ) <EOL> draw = ImageDraw . Draw ( img_grey ) <EOL> img_array = np . asarray ( img_grey ) <EOL> font_sizes , positions , orientations , colors = [ ] , [ ] , [ ] , [ ] <EOL> font_size = self . max_font_size <EOL> last_freq = <NUM_LIT:1.> <EOL> for word , freq in frequencies : <EOL> rs = self . relative_scaling <EOL> if rs != <NUM_LIT:0> : <EOL> font_size = int ( round ( ( rs * ( freq / float ( last_freq ) ) + ( <NUM_LIT:1> - rs ) ) * font_size ) ) <EOL> while True : <EOL> font = ImageFont . truetype ( self . font_path , font_size ) <EOL> if random_state . random ( ) < self . prefer_horizontal : <EOL> orientation = None <EOL> else : <EOL> orientation = Image . ROTATE_90 <EOL> transposed_font = ImageFont . TransposedFont ( font , <EOL> orientation = orientation ) <EOL> box_size = draw . textsize ( word , font = transposed_font ) <EOL> result = occupancy . sample_position ( box_size [ <NUM_LIT:1> ] + self . margin , <EOL> box_size [ <NUM_LIT:0> ] + self . margin , <EOL> random_state ) <EOL> if result is not None or font_size == <NUM_LIT:0> : <EOL> break <EOL> font_size -= self . font_step <EOL> if font_size < self . min_font_size : <EOL> break <EOL> x , y = np . array ( result ) + self . margin // <NUM_LIT:2> <EOL> draw . text ( ( y , x ) , word , fill = "<STR_LIT>" , font = transposed_font ) <EOL> positions . append ( ( x , y ) ) <EOL> orientations . append ( orientation ) <EOL> font_sizes . append ( font_size ) <EOL> colors . append ( self . color_func ( word , font_size = font_size , <EOL> position = ( x , y ) , <EOL> orientation = orientation , <EOL> random_state = random_state , <EOL> font_path = self . font_path ) ) <EOL> if self . mask is None : <EOL> img_array = np . asarray ( img_grey ) <EOL> else : <EOL> img_array = np . asarray ( img_grey ) + boolean_mask <EOL> occupancy . update ( img_array , x , y ) <EOL> last_freq = freq <EOL> self . layout_ = list ( zip ( frequencies , font_sizes , positions , orientations , colors ) ) <EOL> return self <EOL> def process_text ( self , text ) : <EOL> """<STR_LIT>""" <EOL> self . stopwords_lower_ = set ( map ( str . lower , self . stopwords ) ) <EOL> d = { } <EOL> flags = ( re . UNICODE if sys . version < '<STR_LIT:3>' and type ( text ) is unicode <EOL> else <NUM_LIT:0> ) <EOL> regexp = self . regexp if self . regexp is not None else r"<STR_LIT>" <EOL> for word in re . findall ( regexp , text , flags = flags ) : <EOL> if word . isdigit ( ) : <EOL> continue <EOL> word_lower = word . lower ( ) <EOL> if word_lower in self . stopwords_lower_ : <EOL> continue <EOL> try : <EOL> d2 = d [ word_lower ] <EOL> except KeyError : <EOL> d2 = { } <EOL> d [ word_lower ] = d2 <EOL> d2 [ word ] = d2 . get ( word , <NUM_LIT:0> ) + <NUM_LIT:1> <EOL> for key in list ( d . keys ( ) ) : <EOL> if key . endswith ( '<STR_LIT:s>' ) : <EOL> key_singular = key [ : - <NUM_LIT:1> ] <EOL> if key_singular in d : <EOL> dict_plural = d [ key ] <EOL> dict_singular = d [ key_singular ] <EOL> for word , count in dict_plural . items ( ) : <EOL> singular = word [ : - <NUM_LIT:1> ] <EOL> dict_singular [ singular ] = dict_singular . get ( singular , <NUM_LIT:0> ) + count <EOL> del d [ key ] <EOL> d3 = { } <EOL> for d2 in d . values ( ) : <EOL> first = max ( d2 . items ( ) , key = item1 ) [ <NUM_LIT:0> ] <EOL> d3 [ first ] = sum ( d2 . values ( ) ) <EOL> return d3 <EOL> def generate_from_text ( self , text ) : <EOL> """<STR_LIT>""" <EOL> words = self . process_text ( text ) <EOL> self . generate_from_frequencies ( words . items ( ) ) <EOL> return self <EOL> def generate ( self , text ) : <EOL> """<STR_LIT>""" <EOL> return self . generate_from_text ( text ) <EOL> def _check_generated ( self ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( self , "<STR_LIT>" ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> def to_image ( self ) : <EOL> self . _check_generated ( ) <EOL> if self . mask is not None : <EOL> width = self . mask . shape [ <NUM_LIT:1> ] <EOL> height = self . mask . shape [ <NUM_LIT:0> ] <EOL> else : <EOL> height , width = self . height , self . width <EOL> img = Image . new ( self . mode , ( int ( width * self . scale ) , int ( height * self . scale ) ) , <EOL> self . background_color ) <EOL> draw = ImageDraw . Draw ( img ) <EOL> for ( word , count ) , font_size , position , orientation , color in self . layout_ : <EOL> font = ImageFont . truetype ( self . font_path , int ( font_size * self . scale ) ) <EOL> transposed_font = ImageFont . TransposedFont ( font , <EOL> orientation = orientation ) <EOL> pos = ( int ( position [ <NUM_LIT:1> ] * self . scale ) , int ( position [ <NUM_LIT:0> ] * self . scale ) ) <EOL> draw . text ( pos , word , fill = color , font = transposed_font ) <EOL> return img <EOL> def recolor ( self , random_state = None , color_func = None ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( random_state , int ) : <EOL> random_state = Random ( random_state ) <EOL> self . _check_generated ( ) <EOL> if color_func is None : <EOL> color_func = self . color_func <EOL> self . layout_ = [ ( word_freq , font_size , position , orientation , <EOL> color_func ( word = word_freq [ <NUM_LIT:0> ] , font_size = font_size , <EOL> position = position , orientation = orientation , <EOL> random_state = random_state , font_path = self . font_path ) ) <EOL> for word_freq , font_size , position , orientation , _ in self . layout_ ] <EOL> return self <EOL> def to_file ( self , filename ) : <EOL> """<STR_LIT>""" <EOL> img = self . to_image ( ) <EOL> img . save ( filename ) <EOL> return self <EOL> def to_array ( self ) : <EOL> """<STR_LIT>""" <EOL> return np . array ( self . to_image ( ) ) <EOL> def __array__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . to_array ( ) <EOL> def to_html ( self ) : <EOL> raise NotImplementedError ( "<STR_LIT>" ) </s>
