更改 Seaborn 中热图的宽度以补偿字体大小的减小 [英] Changing width of heatmap in Seaborn to compensate for font size reduction

查看:45
本文介绍了更改 Seaborn 中热图的宽度以补偿字体大小的减小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一句话喜欢说

嘿,我今天感觉很无聊,日子也很无聊

我通过 openai 情感代码传递它,该代码为我提供了一些神经元权重,这些权重可以等于或略大于单词数.

神经元权重是

[ 0.01258736, 0.03544582, 0.08490616, 0.09010842, 0.07180552,0.07271874, 0.08906463, 0.09690772, 0.10281454, 0.08131664,0.08315734, 0.0790544, 0.07770097, 0.07302617, 0.07329235,0.06856266, 0.07642639, 0.08199468, 0.09079508, 0.09539193,0.09061056, 0.07109602, 0.02138061, 0.02364372, 0.00322057,0.01517018, 0.01150052, 0.00627739, 0.00445003, 0.00061127,0.0228037、-0.29226044、-0.40493113、-0.4069235、-0.39796737、-0.39871565, -0.39242673, -0.3537892, -0.3779315, -0.36448184,-0.36063945, -0.3506464, -0.36719123, -0.37997353, -0.35103855,-0.34472692, -0.36256564, -0.35900915, -0.3619383, -0.3532831,-0.35352525, -0.33328298, -0.32929575, -0.33149993, -0.32934144,-0.3261477 , -0.32421976, -0.3032671 , -0.47205922, -0.46902984,-0.45346943, -0.4518705, -0.50997925, -0.50997925]

现在我想要做的是绘制一个热图,正值表示积极情绪,而负值表示消极情绪,我正在绘制热图,但热图没有按照应有的方式绘制

但是当句子变长时,整个句子变得越来越小,看不到,那么我应该做些什么改变才能让它显示得更好.

这是我的绘图功能:

def plot_neuron_heatmap(text, values, savename=None, negate=False, cell_height=.112, cell_width=.92):#n_limit = 832cell_height=.325cell_width=.15n_limit = 计数num_chars = len(文本)text = list(map(lambda x: x.replace('\n', '\\n'), text))num_chars = len(文本)total_chars = math.ceil(num_chars/float(n_limit))*n_limit掩码 = np.array([0]*num_chars + [1]*(total_chars-num_chars))text = np.array(text+[' ']*(total_chars-num_chars))values = np.array((values+[0])*(total_chars-num_chars))values = values.reshape(-1, n_limit)text = text.reshape(-1, n_limit)mask = mask.reshape(-1, n_limit)num_rows = len(值)plt.figure(figsize=(cell_width*n_limit, cell_height*num_rows))hmap=sns.heatmap(values, annot=text, mask=mask, fmt='', vmin=-5, vmax=5, cmap='RdYlGn',xticklabels=False, yticklabels=False, cbar=False)plt.subplots_adjust()#plt.tight_layout()plt.savefig('fig1.png')#plt.show()

这就是它如何将冗长的文本显示为

我想让它显示什么

这是完整笔记本的链接:它真正应该做的是

解决方案

您所看到的字体缩小是意料之中的.当您水平添加更多字符时,字体会缩小以适应所有内容.对此有几种解决方案.最简单的方法是将您的文本分成更小的块,并在您想要的输出中显示它们.此外,您可以使用屏幕上显示的不同 DPI 打印图形,以便字母在图像文件中看起来很好.

您应该考虑在此过程中清理您的函数:

  1. count 似乎是一个从未使用过的全局变量.
  2. 您无需使用原始值(例如 num_chars 和输入参数)即可重新定义变量.
  3. 你有一大堆你没有真正使用的变量.
  4. 您多次重新计算大量数量.
  5. 表达式 list(map(lambda x: x.replace('\n', '\\n'), text)) 完全是矫枉过正:list(text.replace('\n', '\\n')) 做同样的事情.
  6. 鉴于 len(values) != len(text) 在大多数情况下,行 values = np.array((values+[0])*(total_chars-num_chars)) 是无稽之谈,需要清理.
  7. 您正在通过对列表进行填充操作来构建 numpy 数组,而不是使用 numpy 的强大功能.
  8. 您已经拥有用于正确改造阵列的整个基础架构,但您没有使用它.

下面的更新版本修复了小问题,并添加了n_limit 作为参数,它决定了您愿意在热图中的一行中包含多少个字符.正如我在上一项中提到的,您已经拥有所有必要的代码来正确地重塑您的数组,甚至有时会掩盖您最终得到的额外尾部.唯一错误的是形状中的 -1 ,由于形状的其余部分,它总是解析为一行.此外,该图始终以 100dpi 保存,因此无论您最终得到多少行,结果都应该与给定的宽度一致.DPI 会影响 PNG,因为它会增加或减少图像中的总像素数,而 PNG 实际上并不理解 DPI:

def plot_neuron_heatmap(text, values, n_limit=80, savename='fig1.png',cell_height=0.325,cell_width=0.15,dpi=100):text = text.replace('\n', '\\n')text = np.array(list(text + ' ' * (-len(text) % n_limit)))如果 len(values) >字体大小:values = np.array(values[:text.size])别的:t = 值值 = np.zeros(text.shape, dtype=np.int)值[:len(t)] = ttext = text.reshape(-1, n_limit)values = values.reshape(-1, n_limit)# mask = np.zeros(values.shape, dtype=np.bool)# mask.ravel()[values.size:] = Trueplt.figure(figsize=(cell_width * n_limit, cell_height * len(text)))hmap = sns.heatmap(values, annot=text, fmt='', vmin=-5, vmax=5, cmap='RdYlGn', xticklabels=False, yticklabels=False, cbar=False)plt.subplots_adjust()plt.savefig(savename if savename else 'fig1.png', dpi=dpi)

以下是该函数的几个示例运行:

text = '嘿,我今天感觉很无聊,今天也很无聊'values = [...] # 您问题中的内容plot_neuron_heatmap(文本,值)plot_neuron_heatmap(文本,值,20)plot_neuron_heatmap(文本,值,7)

结果为以下三个数字:

I have a sentence like say

Hey I am feeling pretty boring today and the day is dull too

I pass it through the openai sentiment code which gives me some neuron weights which can be equal or little greater then number of words.

Neuron weights are

[ 0.01258736,  0.03544582,  0.08490616,  0.09010842,  0.07180552,
        0.07271874,  0.08906463,  0.09690772,  0.10281454,  0.08131664,
        0.08315734,  0.0790544 ,  0.07770097,  0.07302617,  0.07329235,
        0.06856266,  0.07642639,  0.08199468,  0.09079508,  0.09539193,
        0.09061056,  0.07109602,  0.02138061,  0.02364372,  0.00322057,
        0.01517018,  0.01150052,  0.00627739,  0.00445003,  0.00061127,
        0.0228037 , -0.29226044, -0.40493113, -0.4069235 , -0.39796737,
       -0.39871565, -0.39242673, -0.3537892 , -0.3779315 , -0.36448184,
       -0.36063945, -0.3506464 , -0.36719123, -0.37997353, -0.35103855,
       -0.34472692, -0.36256564, -0.35900915, -0.3619383 , -0.3532831 ,
       -0.35352525, -0.33328298, -0.32929575, -0.33149993, -0.32934144,
       -0.3261477 , -0.32421976, -0.3032671 , -0.47205922, -0.46902984,
       -0.45346943, -0.4518705 , -0.50997925, -0.50997925]

Now what I wanna do is plot a heatmap , the positive values shows positive sentiments while negative ones shows negative sentiment and I am plotting the heat map but the heatmap isn't plotting like it should be

But when the sentence gets longer the whole sentence gets smaller and smaller that can't be seen ,So what changes should I do to make it show better.

Here is my plotting function:

def plot_neuron_heatmap(text, values, savename=None, negate=False, cell_height=.112, cell_width=.92):
    #n_limit = 832
    cell_height=.325
    cell_width=.15
    n_limit = count
    num_chars = len(text)
    text = list(map(lambda x: x.replace('\n', '\\n'), text))
    num_chars = len(text)
    total_chars = math.ceil(num_chars/float(n_limit))*n_limit
    mask = np.array([0]*num_chars + [1]*(total_chars-num_chars))
    text = np.array(text+[' ']*(total_chars-num_chars))
    values = np.array((values+[0])*(total_chars-num_chars))

    values = values.reshape(-1, n_limit)
    text = text.reshape(-1, n_limit)
    mask = mask.reshape(-1, n_limit)
    num_rows = len(values)
    plt.figure(figsize=(cell_width*n_limit, cell_height*num_rows))
    hmap=sns.heatmap(values, annot=text, mask=mask, fmt='', vmin=-5, vmax=5, cmap='RdYlGn',xticklabels=False, yticklabels=False, cbar=False)
    plt.subplots_adjust() 
    #plt.tight_layout()
    plt.savefig('fig1.png')
    #plt.show()

This is how it shows the lengthy text as

What I want it to show

Here is a link to the full notebook: https://github.com/yashkumaratri/testrepo/blob/master/heatmap.ipynb

Mad Physicist , Your code does this and what really it should do is

解决方案

The shrinkage of the font you are seeing is to be expected. As you add more characters horizontally, the font shrinks to fit everything in. There are a couple of solutions for this. The simplest would be to break your text into smaller chunks, and display them as you show in your desired output. Also, you can print your figure with a different DPI with what is shown on the screen, so that the letters will look fine in the image file.

You should consider cleaning up your function along the way:

  1. count appears to be a global that is never used.
  2. You redefine variables without ever using the original value (e.g. num_chars and the input parameters).
  3. You have a whole bunch of variables you don't really use.
  4. You recompute a lot of quantities multiple times.
  5. The expression list(map(lambda x: x.replace('\n', '\\n'), text)) is total overkill: list(text.replace('\n', '\\n')) does the same thing.
  6. Given that len(values) != len(text) for most cases, the line values = np.array((values+[0])*(total_chars-num_chars)) is nonsense and needs cleanup.
  7. You are constructing numpy arrays by doing padding operations on lists, instead of using the power of numpy.
  8. You have the entire infrastructure for properly reshaping your arrays already in place, but you don't use it.

The updated version below fixes the minor issues and adds n_limit as a parameter, which determines how many characters you are willing to have in a row of the heat map. As I mentioned in the last item, you already have all the necessary code to reshape your arrays properly, and even mask out the extra tail you end up with sometimes. The only thing that is wrong is the -1 in the shape, which always resolves to one row because of the remainder of the shape. Additionally, the figure is always saved at 100dpi, so the results should come out consistent for a given width, no matter how many rows you end up with. The DPI affects PNG because it increases or decreases the total number of pixels in the image, and PNG does not actually understand DPI:

def plot_neuron_heatmap(text, values, n_limit=80, savename='fig1.png',
                        cell_height=0.325, cell_width=0.15, dpi=100):
    text = text.replace('\n', '\\n')
    text = np.array(list(text + ' ' * (-len(text) % n_limit)))
    if len(values) > text.size:
        values = np.array(values[:text.size])
    else:
        t = values
        values = np.zeros(text.shape, dtype=np.int)
        values[:len(t)] = t
    text = text.reshape(-1, n_limit)
    values = values.reshape(-1, n_limit)
    # mask = np.zeros(values.shape, dtype=np.bool)
    # mask.ravel()[values.size:] = True
    plt.figure(figsize=(cell_width * n_limit, cell_height * len(text)))
    hmap = sns.heatmap(values, annot=text, fmt='', vmin=-5, vmax=5, cmap='RdYlGn', xticklabels=False, yticklabels=False, cbar=False)
    plt.subplots_adjust()
    plt.savefig(savename if savename else 'fig1.png', dpi=dpi)

Here are a couple of sample runs of the function:

text = 'Hey I am feeling pretty boring today and the day is dull too'
values = [...] # The stuff in your question

plot_neuron_heatmap(text, values)
plot_neuron_heatmap(text, values, 20)
plot_neuron_heatmap(text, values, 7)

results in the following three figures:

这篇关于更改 Seaborn 中热图的宽度以补偿字体大小的减小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆