Python &引用;“干净”;在matplotlib中将单词用作标记的方法?使字体大小和颜色不同?
假设我有下面的3x3矩阵: [苹果19 3.5] [橙子07 2.2] [现场][23 7.8] 只有在现实生活中,矩阵才有几十行,而不仅仅是三行 我想创建一个XY图,其中第二列是X坐标,第三列是Y坐标,单词本身(即第一列)是标记(因此没有点、线或任何其他符号) 我还希望每个单词的字体大小由第二列决定(例如,在上面的例子中,这意味着制作“葡萄”的大小大约是“橙子”的三倍) 最后,我想在第三列对应的红蓝比例上给单词上色,0=最深的红色,10=最深的蓝色Python &引用;“干净”;在matplotlib中将单词用作标记的方法?使字体大小和颜色不同?,python,matplotlib,Python,Matplotlib,假设我有下面的3x3矩阵: [苹果19 3.5] [橙子07 2.2] [现场][23 7.8] 只有在现实生活中,矩阵才有几十行,而不仅仅是三行 我想创建一个XY图,其中第二列是X坐标,第三列是Y坐标,单词本身(即第一列)是标记(因此没有点、线或任何其他符号) 我还希望每个单词的字体大小由第二列决定(例如,在上面的例子中,这意味着制作“葡萄”的大小大约是“橙子”的三倍) 最后,我想在第三列对应的红蓝比例上给单词上色,0=最深的红色,10=最深的蓝色 在Python2.x中,最好的方法是什么?我
在Python2.x中,最好的方法是什么?我知道我可以使用matplotlib的“注释”和“文本”来做很多(如果不是全部的话)这些事情,但不知何故,这感觉像是一种变通方法。肯定有一种方法可以将这些词声明为标记(所以我不必将它们视为“注释”)?也许是matplotlib之外的东西?有人做过类似的事情吗?因为你不想使用
注释
或文本
下一个最好的方法是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()
这种方法有几个问题
- 在数学文本中使用
使其不是斜体,似乎会打断matplotlib\textrm{}
- 字母大小需要手动调整(因此系数为700)
使用colormap可能比简单地定义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])
此解决方案有其自身的优点和缺点:
- 主要缺点:正如圆点所示,我无法正确地将文本居中。相反,所需的值是图片的左下角
- 主要优点:这没有乳胶问题,并且使用“真实”标记路径,这意味着它可以很容易地用于标记线图(但不是原始问题)
如果您有许多行/标记,则通过“文本”或“注释”上的简单循环执行上述操作将非常缓慢,而这会更好地扩展。这很有效。RdBu颜色贴图给了我想要的颜色比例。不过还是有点解决办法。我将尝试调整matplotlib的源代码,看看是否可以根据字符串列表添加新的自定义标记。如果我能做到的话,我会把代码贴在这里。
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)