在matplotlib中使用单词作为标记的“干净”方式?使字体大小和颜色不同?

2024-06-26 00:00:47 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有下面的3x3矩阵:

[苹果19 3.5]

[橙子07 2.2]

[葡萄23 7.8]

只有在现实生活中矩阵才有几十行,而不仅仅是三行。

我想创建一个X Y绘图,其中第二列是X坐标,第三列是Y坐标,单词本身(即第一列)是标记(因此没有点、线或任何其他符号)。

我还希望每个单词的字体大小由第二列决定(例如,在上面的示例中,这意味着使“grapes”的大小大约是“oranges”的三倍)。

最后,我想将单词按红到蓝的比例上色,对应于第三列,0=最深的红色,10=最深的蓝色。

在Python2.x中最好的方法是什么?我知道我可以使用matplotlib的“annotate”和“text”来做很多(如果不是全部的话)这些事情,但不知怎么的,这感觉像是一个解决方法。当然,肯定有一种方法可以将单词声明为标记(所以我不必将它们视为“注释”)?也许是matplotlib之外的东西?有人做过类似的事情吗?


Tags: 方法标记苹果绘图示例matplotlib符号矩阵
2条回答

由于您不想使用annotatetext,下一个最好的方法是py.scatter,它将接受一个标记

``'$...$'``                    render the string using mathtext.

例如

import pylab as py

data = [["peach", 1.0, 1.0], 
        ["apples", 19, 3.5], 
        ["oranges", 7, 2.2], 
        ["grapes", 23, 7.8]]

for item in data:
    py.scatter(item[1], item[2], s=700*item[1], 
           c=(item[2]/10.0, 0, 1 - item[2]/10.0), 
           marker=r"$ {} $".format(item[0]), edgecolors='none' )

py.show()

Example

这种方法有几个问题

  • 在数学文本中使用\textrm{}使其不是斜体似乎会破坏matplotlib
  • 字母大小需要手动调整(因此系数为700)

最好使用颜色映射,而不是简单地定义RGB颜色值。

当我四处寻找相同问题的解决方案时,我发现了一个看起来更干净的方法(或者至少在精神上更接近最初的问题),即使用TextPath:

from matplotlib import pyplot as plt
from matplotlib.text import TextPath

data = [["peach", 1.0, 1.0], 
        ["apples", 19, 3.5], 
        ["oranges", 7, 2.2], 
        ["grapes", 23, 7.8]]

max_d2 = max([d[2] for d in data]) + 1e-3
max_d1 = max([d[1] for d in data]) + 1e-3

cmap = plt.get_cmap('RdBu')
for d in data:
    path = TextPath((0,0), d[0])

    # These dots are to display the weakness below, remove for the actual question
    plt.plot(d[1],d[2],'.',color='k')

    plt.plot(d[1],d[2],marker=path,markersize=100, color=cmap(d[2]/max_d2))
plt.xlim([0,max_d1+5])
plt.ylim([0,max_d2+0.5])

Output image

这种解决方案本身有一些优点和缺点:

  • 主要缺点:正如圆点所显示的,我无法正确地将文本居中。相反,所需的值是图片的左下角。
  • 主要优点:这没有乳胶问题,使用“真正的”标记路径,这意味着它可以很容易地用于标记线图(但不是最初的问题)

代码:

import numpy as np
x = np.cumsum(np.random.randn(100,5), axis=0)

plt.figure(figsize=(15,5))
for i in range(5):
    label = TextPath((0,0), str(i), linewidth=1)
    plt.plot(x[:,i], color='k')
    plt.plot(np.arange(0,len(x),5),x[::5,i], color='k', marker=label, markersize=15, linewidth=0)

Output for line plot

如果有很多行/标记,通过简单的“文本”或“注释”循环执行上述操作将非常缓慢,而这可以更好地扩展。

相关问题 更多 >