五更了,这一次应评论区小伙伴要求,画汉字的热力图。 @诸葛不亮@夕雪@polarlion。这回不再随机选,而是依次画 Unicode 列表里汉字的前「1,10,100,1k,10k,20k」叠加的热力图效果。很有意思的是前 1000 个汉字情形能明显的看出左右结构,存在大量单人旁的字。一直到画完所有的 2 万字左右依然可隐约看出左右结构。@王赟 Maigo

四更下,有小伙伴 @兴趣宝贝 提出将汉字谚文与平假名片假名横向比较有失公允。下面直接比较下汉字偏旁部首,平假名 / 片假名,韩语字母。三者总数量很接近,随机取相同数目展示如下:

再更下,多谢 @王赟 Maigo 指正,韩语 Unicode 只到 D7A3,共计 11172 字「少了 11 个」。
多谢 @王赟 Maigo@Wayne 提出日语字体的问题。最后面补上不同日语字体的比较。
「二更」受高赞回答启发,一并把日语和韩语的动图也画了。日语当然仅仅是平假名和片假名。最终看起来汉字的确是方块字。韩语排列组合拼凑的痕迹太明显,叠加字数不太多的时候具有明显的上下结构。日语平假名和片假名合起来像个球。哈哈。
虽然不懂语言学,但是用 matplotlib 简单的画了下,效果如下:
汉字:
汉字叠加效果 https://www.zhihu.com/video/1244262404227670016
画图的时候刻意给汉字设置了 5%的透明度,当总数到 200 基本就是一团黑了。但是一直画到 2 万字依然感觉黑色区域总面积还在增加。
韩语:
韩语叠加效果 https://www.zhihu.com/video/1244474986271789056
日语平假名 / 片假名
日语平假名 / 片假名叠加效果 https://www.zhihu.com/video/1244482295828426752
或许是因为平假名 / 片假名一共只有 90 几个字符,或许是其采用了草书效果,真的看起来像个球。
横向比较下,中日韩三语各随机取 90 个字符「日语可取的太少了」如下:

补充下不同日语字体的比较,这些字体是 Mac 上 matplotlib 自带的。画图的时候采用了相同的字体大小,那个像个球的中易黑体明显比其他小很多。

matplotlib 画图使用的是 Unicode:
- 中文:u4E00-u9FD5, 共 20949 个汉字
- 韩文:uAC00-uD7AF,共 11183 个字
- 日文平假名 u3040 - u309f,共 46 字
- 日文片假名 u30a0 - u30ff,共 46 字
代码如下:
import random
def chinese(num):
'''随机选取 num 个中文字符'''
chineselist = [chr(i) for i in range(0x4E00,0x9FD5+1)]
return random.sample(chineselist, num)
def japanese(num):
'''随机选取 num 个日文总平假名 / 片假名数字符'''
japaneselist = [chr(i) for i in range(0x3041, 0x309f+1) if not (i == 0x3097 or i == 0x3098 )] + [chr(i) for i in range(0x30a0, 0x30ff+1)]
return random.sample(japaneselist, num)
def korean(num):
'''随机选取 num 个韩文字符'''
koreanlist = [chr(i) for i in range(0xAC00, 0xD7AF+1)]
return random.sample(koreanlist, num)
示例图:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import font_manager
fontP = font_manager.FontProperties()
fontP.set_family('SimHei')
fontP.set_size(200)
fontP1 = font_manager.FontProperties()
fontP1.set_family('SimHei')
fontP3 = font_manager.FontProperties()
fontP3.set_family('AppleGothic')
fontP3.set_size(200)
fig, axs = plt.subplots(1,3, figsize = (12,4), dpi = 100)
plt.subplots_adjust(wspace = 0.1)
num = 90
labels = ['汉字','日语', '韩语']
for i in range(len(axs)):
axs[i].axis('off')
rect = patches.Rectangle((0.05,0.05),0.9,0.9,linewidth=1,edgecolor='r',facecolor='none')
axs[i].add_patch(rect)
axs[i].set_title(labels[i], fontproperties=fontP1, fontsize = 20 )
for t in chinese(num):
axs[0].text(0.03,0.16, r'%s'%(t), fontproperties=fontP, transform = axs[0].transAxes, alpha = 0.05)
for t in japanese(num):
axs[1].text(0.03,0.16, r'%s'%(t), fontproperties=fontP, transform = axs[1].transAxes, alpha = 0.05)
for t in korean(num):
axs[2].text(0.03,0.16, r'%s'%(t), fontproperties=fontP3, transform = axs[2].transAxes, alpha = 0.05)
plt.savefig('cjk.png', dpi = 300, bbox_inches = 'tight')