假设我有以下3x3矩阵:
[苹果19 3.5]
[oranges 07 2.2]
[grape 23 7.8]
只有在现实生活中,矩阵才有几十行,而不仅仅是三行。
我想创建一个XY图,其中第二列是X坐标,第三列是Y坐标,单词本身(即第一列)是标记(所以没有点,线或任何其他符号)。
我还希望每个单词的字体大小由第二列确定(在上面的示例中,这意味着使“葡萄”的大小约为“橙子”的三倍)。
最后,我想对与第三列对应的红色到蓝色刻度的颜色进行着色,0 =最暗的红色,10 =最暗的蓝色。
Python 2.x中最好的方法是什么?我知道我可以使用matplotlib的“annotate”和“text”来做很多(如果不是全部)这些事情,但不知怎的,这感觉就像一个解决方法。当然必须有一种方法来宣称单词是标记(所以我不必将它们视为“注释”)?也许在matplotlib之外的东西?有没有人做过类似的事情?
答案 0 :(得分:11)
由于您不想使用annotate
或text
,下一个最好的事情是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()
此方法有几个问题
\textrm{}
以使其不是斜体似乎会破坏matplotlib 使用色彩图而不是简单地定义RGB色值可能会更好。
答案 1 :(得分:2)
在寻找同一问题的解决方案的同时,我发现了一个看起来更清洁的问题(或者至少更符合原始问题的要求),即使用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])
这个解决方案有一些优点和缺点:
代码:
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)
如果您有很多行/标记,那么通过“文本”或“注释”的简单循环执行上述操作会非常慢,而这会更好地扩展。