【问题标题】:Wordcloud - relative font size amongst multiple instances?Wordcloud - 多个实例之间的相对字体大小?
【发布时间】:2022-01-19 09:19:11
【问题描述】:

我正在使用wordcloud==1.8.1 来渲染具有多个词云的情节,
每个人都在条形图中成为一个条形。

基本上只是像这样添加一些子图:

subplot = plt.subplot(1, len(ontologies), i, anchor='S')
subplot.set_title(title, size=10, y=-0, pad=-25)
subplot.set_ymargin(50)
plt.plot()
cloud = WordCloud(
    font_path=f'{current_dir}/assets/source-sans-pro.ttf',
    background_color='white',
    width=width,
    height=height,
    # max_words=30,
    prefer_horizontal=0.99,
    color_func=lambda *args, **kwargs: colors[ontology_name]
)
plt.imshow(cloud.generate_from_frequencies(
    frequencies
    #max_font_size=200,
    #min_font_size=10,
))
plt.axis("off")

是否有可能在所有字云中获得正确的相对字体大小?在同一个词云中,它们只是相对于彼此的那一刻。

我尝试根据频率动态设置min_font_sizemax_font_size,但这些似乎并不影响关系...

因此,如果一个单词在文档中出现的频率比其他单词高 10 倍,我希望它的字体比所有其他单词大 10 倍。无论在哪个 wordcloud 中。

frequencies 只是单词出现总数的字典:

wordcloud 1 (200x400) {'word1': 10, 'word2': 40}
词云 2 (200x600) {'word3': 20, 'word4': 80}
词云 2 (200x800) {'word5': 40, 'word6': 160}

那么,如何从中创建 3 个 wordcloud 并保持比例,使 wordcloud 3 中的 word6 比 wordcloud 1 中的 word1 大 16 倍?

【问题讨论】:

  • 您没有在 sn-p 中定义frequencies,但大概您可以更改每个频率中的总体,以便它们都归一化为同一事物。还有relative_scaling,您也许可以根据人口进行修改。
  • 您应该将relative_scaling 设置为1,以便字体大小与频率(每个文档)成正比。默认为0.5,它根据频率和排名确定字体大小,请参阅source。使用1,第二个和变为零。
  • 非常感谢。那么我只需要根据当前的 wordcloud 维度来缩放频率?
  • (用更多数据更新了问题...)
  • 事实证明这似乎是不可能的,因为generate_from_frequencies 不采用 frequencies 而是 counts 并在内部计算相对于字典中计数最高的单词的频率,因此您无法相对于彼此缩放不同的字数字典。我在上面删除了错误的 cmets。

标签: python matplotlib word-cloud


【解决方案1】:

我能够为玩具示例获得所需的结果,但我不能 100% 确定当图像变得更加拥挤时这是否适用于更大的集合,并且对于您示例中的垂直条很可能会失败(也许将prefer_horizontal 设置为较低的值,比如0.1,在这种情况下可能会有所帮助,旋转大部分单词)。

需要注意以下几点:

  • relative_scaling 设置为1,以便字体大小与频率(每个文档)成正比。
  • 使图像足够宽,以使最大的单词在其整个长度上都适合图像(否则可能会缩小)
  • font_step 设置为0 以防止在第一次尝试不适合单词时字体减少(请参阅source

以下示例说明了这一点(颜色和单词位置是随机选择的,因此您的结果会有所不同,但大小和大小比例应与示例输出中的相同):

import matplotlib.pyplot as plt
import wordcloud

wl1 = {'word1': 10, 'word2': 40}
wl2 = {'word3': 20, 'word4': 80}
wl3 = {'word5': 40, 'word6': 160}

# get max word count per list
w1 = max((v for k,v in wl1.items()))
w2 = max((v for k,v in wl2.items()))
w3 = max((v for k,v in wl3.items()))

# get total max for scaling factor among lists
w_max = max(w1, w2, w3)

height = 400
kwargs = {'relative_scaling': 1, 'height': height, 'width': 4*height,
          'prefer_horizontal': 1, 'font_step': 0 }

wc1 = (wordcloud.WordCloud(**kwargs)
       .generate_from_frequencies(wl1, max_font_size=w1/w_max*height))
wc2 = (wordcloud.WordCloud(**kwargs)
       .generate_from_frequencies(wl2, max_font_size=w2/w_max*height))
wc3 = (wordcloud.WordCloud(**kwargs)
       .generate_from_frequencies(wl3, max_font_size=w3/w_max*height))


fig, axes = plt.subplots(3, layout='constrained', figsize=(10,8))
for ax, wc in zip(axes.flat, (wc1, wc2, wc3)):
    ax.imshow(wc.to_image())
    ax.axis('off')

【讨论】:

  • 太棒了,我想这是尽可能接近那个图书馆 - 谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
  • 2012-05-06
  • 1970-01-01
  • 2011-03-27
相关资源
最近更新 更多