使用Python创建信息图表

5
我想用Python创建一个简单的信息图表。Matplotlib似乎有很多功能,但没有覆盖我这个简单的热力图网格示例的内容。
该信息图表是一个简单的5 x 5网格,内部数字范围为0到1。然后,网格方块将被着色为0=白色,1=蓝色,0.5为浅蓝色。
Matplotlib可能可以使用,但我找不到或结合任何示例来生成它。
任何见解、示例代码或库方向都会非常有帮助。
谢谢 Matt

这个图形将如何使用?你会把它放入文档中吗?还是放在网页上? - dan-gph
最初它只是被创建为放入文档中。理想情况下,将来它将会动态生成以放置在网页上。分发机制对方法有很大影响吗? - Matt Alcock
是的,这是有区别的。如果仅在屏幕上查看,那么位图格式可能很好。如果要放入PDF文件中,则矢量格式更好。等等。 - dan-gph
到目前为止,它们确实拥有一个带注释单元格的热图,可以包含范围在[0,1]之间的数字。以下是一个示例,可以转换为答案:https://matplotlib.org/3.1.1/gallery/images_contours_and_fields/image_annotated_heatmap.html#sphx-glr-gallery-images-contours-and-fields-image-annotated-heatmap-py - a.t.
3个回答

4

这取决于你得到图形后需要做什么,Matplotlib允许你交互地在屏幕上显示图形,将其保存为矢量、pdf或位图格式等等。

如果你选择这个框架,imshow将会满足你的需求,下面是一个例子:

# Just some data to test:
from random import gauss
a = [[gauss(0, 10) for i in xrange(0, 5)] for j in xrange(0,5)]

from pylab import * # or just launch "IPython -pylab" from the command line

# We create a custom colormap:
myblue = cm.colors.LinearSegmentedColormap("myblue", {
    'red':   [(0, 1, 1), (1, 0, 0)], 
    'green': [(0, 1, 1), (1, 0, 0)],
    'blue':  [(0, 1, 1), (1, 1, 1)]})

# Plotting the graph:
imshow(a, cmap=myblue)

如需更多关于色图的细节,请查看此链接,这里是imshow的链接 - 或者直接使用help(colors.LinearSegmentedColormap)help(imshow)

alt text http://img522.imageshack.us/img522/6230/bluep.png

(请注意,这是使用标准选项的结果,您可以添加网格、更改过滤等)。


编辑

但我想在网格中显示数字

为了简单起见:

for i in xrange(0,5):
    for j in xrange(0,5):
        text(i, j,
             "{0:5.2f}".format(a[i][j]),
             horizontalalignment="center",
             verticalalignment="center")

这很好,但我想在网格中显示数字。颜色是次要的。此外,这里的着色是逐渐变化的,而不是每个网格方块固定的。 - Matt Alcock
当然,您可以灵活地显示网格、数字格式等。这里就不详细解释了,可以查看他们网站上的演示:http://matplotlib.sourceforge.net/gallery.html - RedGlyph
还有一个评论,如果您需要处理图像(顺便说一下,这是一个很棒的库!),Jonathan建议使用PyCairo可能更合适。Matplotlib更加数学导向,正如您所猜测的那样;-)它也需要一些习惯,使用IPython在控制台中尝试它是一个不错的方式 - 虽然不是必需的:http://ipython.scipy.org/moin/FrontPage - RedGlyph
感谢Jonathan/Red。我在两者之间犹豫不决,我想我会最初使用matplotlib方法(我已经安装了它),如果需要添加额外的细节(如注释等),我会转向cario。感谢大家! - Matt Alcock
我使用了设置插值为“nearest”来确保获得热图效果而不是颗粒化效果。imshow(a, cmap=myblue, interpolation='nearest')再次感谢大家! - Matt Alcock

2

PyCairo是您的好帮手。以下是一个简单的示例:

from __future__ import with_statement
import cairo
img = cairo.ImageSurface(cairo.FORMAT_ARGB32,100,100)
g = cairo.Context(img)
for x in range(0,100,10):
    for y in range(0,100,10):
        g.set_source_rgb(.1 + x/100.0, 0, .1 + y/100.0)
        g.rectangle(x,y,10,10)
        g.fill()
with open('test.png','wb') as f:
    img.write_to_png(f)

输出

您可能会发现这个教程很有帮助。


这很好,但我想在网格中显示数字。颜色是次要的。 - Matt Alcock
2
@Matt:所以...阅读上面的代码,查看Cairo API,并将其调整为呈现文本而不是填充矩形。这有多难? - unwind
1
我同意unwind的看法,最好的方式是尽量确保你对于项目中要使用的工具感到舒适自如! - RedGlyph
好的,听起来Cario拥有我所需要的功能!我会开始进行训练! - Matt Alcock

2
一种可能性是使用Python生成SVG。您可以在Firefox或Inkscape中查看SVG。
这里有一个简单而粗糙的示例:
import random

def square(x, y, value):
    r, g, b = value * 255, value * 255, 255
    s = '<rect x="%d" y="%d" width="1" height="1" style="fill:rgb(%d,%d,%d);"/>' % (x, y, r, g, b)
    t = '<text x="%d" y="%d" font-size=".2" fill="yellow">%f</text>' % (x, y + 1, value)
    return s + '\n' + t

print('''
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1" viewBox="0 0 5 5"
xmlns="http://www.w3.org/2000/svg">
''')
for x in range(0, 5):
    for y in range(0, 5):
        print(square(x, y, random.random()))

print('</svg>')

alt text http://www.imagechicken.com/uploads/1257184721026098800.png

{{链接1:替代文本 http://www.imagechicken.com/uploads/1257184721026098800.png}}


这只是一个hack,尽管它确实生成了我想要的东西!我不知道我的分发机制最终会是什么样子,所以将其与HTML绑定并没有真正帮助。无论如何还是谢谢大家。dangph - Matt Alcock
不错!我想指出我在答案中提到的Cairo库有PDF和SVG“后端”,因此可以使用相同的代码来生成这些不同的格式。但我喜欢你答案的教学简洁性。+1 - Jonathan Feinberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接