【问题标题】:Creating an Infographic In Python在 Python 中创建信息图
【发布时间】:2010-12-12 07:19:49
【问题描述】:

我想在 python 中创建一个简单的信息图。 Matplotlib 似乎有很多功能,但没有什么能涵盖我简单的热图网格示例。

信息图是一个简单的 5 x 5 网格,其内部的数字范围为 0 到 1。网格方块随后将着色为 0=白色 1=蓝色 0.5 为淡蓝色。

可能可以使用 Matplotlib,但我无法找到或组合任何可以深入了解生成此内容的示例。

任何见解、示例代码或库方向都会真正有帮助

问候 马特

【问题讨论】:

  • 图形将如何使用?你打算把它放在一个文件里吗?在网页上?
  • 实际上它只会被装入文件中。在未来理想情况下,这将动态生成以在网页上进行。分布机制对方法有很大影响吗?
  • 是的,它有所作为。如果只在屏幕上查看,那么位图格式可能就可以了。如果要放入PDF,那么矢量格式会更好。等等。
  • 现在他们确实有这样一个带有注释单元格的热图,其中可以包含 [0,1] 范围内的数字。这是一个可以转换为答案的示例:matplotlib.org/3.1.1/gallery/images_contours_and_fields/…

标签: python grid matplotlib charts heatmap


【解决方案1】:

这取决于您在获得图表后需要对它做什么,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)

有关颜色图check this link 的更多详细信息,这里是link for 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")

【讨论】:

  • 这很好,但我希望在网格中显示数字。着色是次要的。此外,这里的颜色是宏伟的,而不是每个网格正方形的固定颜色
  • 给你了,当然你在网格的显示方式、数字的格式等方面有一定的灵活性。在这里解释太长了,他们的网站上有一点炫耀:matplotlib.sourceforge.net/gallery.html
  • 还有一点评论,如果您需要处理图像,乔纳森关于使用 PyCairo 的建议可能更合适(顺便说一下很棒的库!)。正如您可能已经猜到的那样,Matplotlib 更加面向数学;-) 它还需要一些习惯,使用 IPython 是在控制台中尝试它的好方法——尽管不是强制性的:ipython.scipy.org/moin/FrontPage
  • 谢谢乔纳森/瑞德。如果我需要开始添加额外的细节(如注释等),我认为我将首先使用 matplotlib 方法(我已经安装了该方法)并转移到 cario 之间。谢谢大家!
  • 我使用此设置将插值设置为“最近”以确保获得热图感觉而不是颗粒效果。 imshow(a, cmap=myblue, interpolation='nearest') 再次感谢大家!
【解决方案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)

您可能会发现 this tutorial 很有帮助。

【讨论】:

  • 这很好,但我希望在网格中显示数字。颜色是次要的。
  • @Matt:所以...阅读上面的代码,查看 Cairo API,并调整它以呈现文本而不是填充矩形。这有多难?
  • 我同意放松,最好的方法是尝试并确保您对您将用于项目的任何内容感到轻松!
  • 好电话,听起来 cario 有我需要的力量!我要开始训练了!
【解决方案3】:

一种可能性是从 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

【讨论】:

  • 这是一个 hack,尽管它生成的正是我所追求的!我不知道我的分发机制最终会是什么,所以将它与 html 联系起来并没有真正的帮助。感谢所有相同的 dangph
  • 不错!我会指出,我在回答中提到的 Cairo 库具有 PDF 和 SVG“后端”,因此可以使用相同的代码来生成这些不同的格式。但我喜欢你的回答简单易懂。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 2018-05-16
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多