如何绘制元组列表?

78
我有以下数据集。我想使用Python或Gnuplot来绘制数据。元组的形式为(x, y)。Y轴应该是一个对数轴,即log(y)。散点图或折线图都是理想的选择。
如何实现这个目标?
 [(0, 6.0705199999997801e-08), (1, 2.1015700100300739e-08), 
 (2, 7.6280656623374823e-09), (3, 5.7348209304555086e-09), 
 (4, 3.6812203579604238e-09), (5, 4.1572516753310418e-09)]
6个回答

117

如果我正确理解你的问题,你可以这样做。

>>> import matplotlib.pyplot as plt
>>> testList =[(0, 6.0705199999997801e-08), (1, 2.1015700100300739e-08), 
 (2, 7.6280656623374823e-09), (3, 5.7348209304555086e-09), 
 (4, 3.6812203579604238e-09), (5, 4.1572516753310418e-09)]
>>> from math import log
>>> testList2 = [(elem1, log(elem2)) for elem1, elem2 in testList]
>>> testList2
[(0, -16.617236475334405), (1, -17.67799605473062), (2, -18.691431541177973), (3, -18.9767093108359), (4, -19.420021520728017), (5, -19.298411635970396)]
>>> zip(*testList2)
[(0, 1, 2, 3, 4, 5), (-16.617236475334405, -17.67799605473062, -18.691431541177973, -18.9767093108359, -19.420021520728017, -19.298411635970396)]
>>> plt.scatter(*zip(*testList2))
>>> plt.show()

这将为您提供类似以下的内容:

在此输入图片描述

或者以线形图的形式呈现,

>>> plt.plot(*zip(*testList2))
>>> plt.show()

这里输入图片描述

编辑 - 如果您想要为轴添加标题和标签,可以尝试以下方法:

>>> plt.scatter(*zip(*testList2))
>>> plt.title('Random Figure')
>>> plt.xlabel('X-Axis')
>>> plt.ylabel('Y-Axis')
>>> plt.show()

这将为您提供

在此输入图像描述


1
OP问的不太清楚,是想在y轴上使用对数坐标还是想将y坐标设为log(y_data)。您可以使用plt.semilogy()代替plt.plot() - Bennett Brown
8
对于不了解的人来说,星号会将压缩文件反转——相当于解压缩。 - knockNrod
3
我从未见过像这样使用“星号”的东西...这让我想到:“在Python文档的哪里解释了*?”https://dev59.com/Ymcs5IYBdhLWcg3w0HOz - poleguy
1
@knockNrod:如果“the * reverses the zip”,那么为什么要使用*zip(...),在这种情况下它只是一个恒等函数呢? - mins

31

在 matplotlib 中,它将是:

import matplotlib.pyplot as plt

data =  [(0, 6.0705199999997801e-08), (1, 2.1015700100300739e-08),
 (2, 7.6280656623374823e-09), (3, 5.7348209304555086e-09),
 (4, 3.6812203579604238e-09), (5, 4.1572516753310418e-09)]

x_val = [x[0] for x in data]
y_val = [x[1] for x in data]

print x_val
plt.plot(x_val,y_val)
plt.plot(x_val,y_val,'or')
plt.show()

这将产生:

输入图像说明


OP要求y轴为对数坐标。在pyplot交互模式下使用plt.yscale('log') - Bennett Brown

19

像其他回答中所述,scatter()plot()可以生成您想要的图形。我建议对已有答案进行两点改进:

  1. 使用numpy创建x坐标列表和y坐标列表。与其他答案中建议的在Python中使用迭代相比,在numpy中处理大型数据集更快。

  2. 使用pyplot应用对数刻度而不是直接操作数据,除非您确实想要记录日志。

import matplotlib.pyplot as plt
import numpy as np

data = [(2, 10), (3, 100), (4, 1000), (5, 100000)]
data_in_array = np.array(data)
'''
That looks like array([[     2,     10],
                       [     3,    100],
                       [     4,   1000],
                       [     5, 100000]])
'''

transposed = data_in_array.T
'''
That looks like array([[     2,      3,      4,      5],
                       [    10,    100,   1000, 100000]])
'''    

x, y = transposed 

# Here is the OO method
# You could also the state-based methods of pyplot
fig, ax = plt.subplots(1,1) # gets a handle for the AxesSubplot object
ax.plot(x, y, 'ro')
ax.plot(x, y, 'b-')
ax.set_yscale('log')
fig.show()

result

我还使用了ax.set_xlim(1, 6)ax.set_ylim(.1, 1e6)来美化它。

我使用了面向对象的Matplotlib接口。由于它使用创建的对象的名称提供更大的灵活性和明确的清晰度,因此OO接口优先于交互式基于状态的接口。


如果我想要为每个 x 值显示垂直线,就像一个非常窄的条形图(高度达到 y 值),使得绘图看起来像离散和彩色的 1-d 直方图,该怎么办? - Ash
Ash,matplotlib有一个单独的方法可以将条形图添加到轴上,您应该调用它而不是plot。除非我误解了您的问题与此问题的关系,否则请将其作为问题发布,而不是作为对无关问题的回答的评论。 - Bennett Brown

19

您也可以使用zip

import matplotlib.pyplot as plt

l = [(0, 6.0705199999997801e-08), (1, 2.1015700100300739e-08),
     (2, 7.6280656623374823e-09), (3, 5.7348209304555086e-09),
     (4, 3.6812203579604238e-09), (5, 4.1572516753310418e-09)]

x, y = zip(*l)

plt.plot(x, y)

这难道不是与4年前被接受的答案中的解决方案完全相同吗? - natiiix
1
这个答案与之前的相似,但更为简洁明了。与使用 * 代替 x,y 不同,它没有过多华丽的修饰。遗憾的是它并未回答问题的所有部分。不过我仍会支持这个答案。 - poleguy

2

通过使用gnuplotgplot.py

from gplot import *

l = [(0, 6.0705199999997801e-08), (1, 2.1015700100300739e-08), 
 (2, 7.6280656623374823e-09), (3, 5.7348209304555086e-09), 
 (4, 3.6812203579604238e-09), (5, 4.1572516753310418e-09)]

gplot.log('y')
gplot(*zip(*l))

enter image description here


0

也可以用 Pandas 完成。

import pandas as pd
data = [(0, 6.0705199999997801e-08), (1, 2.1015700100300739e-08), 
        (2, 7.6280656623374823e-09), (3, 5.7348209304555086e-09), 
        (4, 3.6812203579604238e-09), (5, 4.1572516753310418e-09)]

pd.DataFrame(data, columns=['l','v']).set_index('l').plot(kind='line');

enter image description here


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