我可以根据简单的'在matplotlib中创建一个简单的柱状图。字典:
import matplotlib.pyplot as plt
D = {u'Label1':26, u'Label2': 17, u'Label3':30}
plt.bar(range(len(D)), D.values(), align='center')
plt.xticks(range(len(D)), D.keys())
plt.show()
但是,我怎么在这个词典的文本和数字数据上创建曲线,我不知道?
Т_OLD = {'10': 'need1', '11': 'need2', '12': 'need1', '13': 'need2', '14': 'need1'}
答案 0 :(得分:3)
您可以使用numpy将字典转换为具有两列的数组,可以绘制。
import matplotlib.pyplot as plt
import numpy as np
T_OLD = {'10' : 'need1', '11':'need2', '12':'need1', '13':'need2','14':'need1'}
x = list(zip(*T_OLD.items()))
# sort array, since dictionary is unsorted
x = np.array(x)[:,np.argsort(x[0])].T
# let second column be "True" if "need2", else be "False
x[:,1] = (x[:,1] == "need2").astype(int)
# plot the two columns of the array
plt.plot(x[:,0], x[:,1])
#set the labels accordinly
plt.gca().set_yticks([0,1])
plt.gca().set_yticklabels(['need1', 'need2'])
plt.show()
以下是一个版本,它独立于字典的实际内容;唯一的假设是密钥可以转换为浮点数。
import matplotlib.pyplot as plt
import numpy as np
T_OLD = {'10': 'run', '11': 'tea', '12': 'mathematics', '13': 'run', '14' :'chemistry'}
x = np.array(list(zip(*T_OLD.items())))
u, ind = np.unique(x[1,:], return_inverse=True)
x[1,:] = ind
x = x.astype(float)[:,np.argsort(x[0])].T
# plot the two columns of the array
plt.plot(x[:,0], x[:,1])
#set the labels accordinly
plt.gca().set_yticks(range(len(u)))
plt.gca().set_yticklabels(u)
plt.show()
答案 1 :(得分:2)
使用y轴刻度的数值,然后使用plt.yticks()
将它们映射到所需的字符串:
import matplotlib.pyplot as plt
import pandas as pd
# example data
times = pd.date_range(start='2017-10-17 00:00', end='2017-10-17 5:00', freq='H')
data = np.random.choice([0,1], size=len(times))
data_labels = ['need1','need2']
fig, ax = plt.subplots()
ax.plot(times, data, marker='o', linestyle="None")
plt.yticks(data, data_labels)
plt.xlabel("time")
注意:使用折线图来表示时间上的分类变化(例如从need1
到need2
)通常不是一个好主意。这样做会给出时间点之间连续性的视觉印象,这可能不准确。在这里,我将绘图样式更改为点而不是线。如果由于某种原因您需要这些行,只需从调用linestyle="None"
中删除plt.plot()
。
<强>更新强>
(根据评论)
要使用任意长度的y轴类别集进行此操作,请使用ax.set_yticks()
和ax.set_yticklabels()
映射到y轴值。
例如,给定一组潜在的y轴值labels
,让N
为labels
子集的大小(此处我们将其设置为4 ,但它可以是任何尺寸)。
然后绘制y值的随机样本data
并绘制时间图,根据完整集labels
标记y轴刻度。请注意,我们仍然首先使用set_yticks()
数字标记,然后使用set_yticklabels()
替换我们的类别标签。
labels = np.array(['A','B','C','D','E','F','G'])
N = 4
# example data
times = pd.date_range(start='2017-10-17 00:00', end='2017-10-17 5:00', freq='H')
data = np.random.choice(np.arange(len(labels)), size=len(times))
fig, ax = plt.subplots(figsize=(15,10))
ax.plot(times, data, marker='o', linestyle="None")
ax.set_yticks(np.arange(len(labels)))
ax.set_yticklabels(labels)
plt.xlabel("time")
答案 2 :(得分:2)
这给出了确切的期望图:
import matplotlib.pyplot as plt
from collections import OrderedDict
T_OLD = {'10' : 'need1', '11':'need2', '12':'need1', '13':'need2','14':'need1'}
T_SRT = OrderedDict(sorted(T_OLD.items(), key=lambda t: t[0]))
plt.plot(map(int, T_SRT.keys()), map(lambda x: int(x[-1]), T_SRT.values()),'r')
plt.ylim([0.9,2.1])
ax = plt.gca()
ax.set_yticks([1,2])
ax.set_yticklabels(['need1', 'need2'])
plt.title('T_OLD')
plt.xlabel('time')
plt.ylabel('need')
plt.show()
对于Python 3.X,绘图线需要将map()
输出显式转换为列表:
plt.plot(list(map(int, T_SRT.keys())), list(map(lambda x: int(x[-1]), T_SRT.values())),'r')
在Python 3.X map()
中返回迭代器而不是Python 2.7中的列表。
该图使用转换为整数的字典键和need1
或need2
的最后一个元素,也转换为整数。这取决于您的数据的特定结构,如果need1
和need3
的值需要更多操作。
在绘制和更改轴限制之后,程序只需修改y位置1和2处的刻度标签。然后它还会添加标题以及x和y轴标签。
重要的是必须对字典/输入数据进行排序。一种方法是使用OrderedDict
。此处T_SRT
是OrderedDict
对象,按T_OLD
中的键排序。
输出结果为:
这是T_OLD
中更多值/标签的更一般情况。它假设标签始终为'needX'
,其中X
为任意数字。对于数字前面的任何字符串的一般情况,可以很容易地做到这一点,尽管它需要更多的处理,
import matplotlib.pyplot as plt
from collections import OrderedDict
import re
T_OLD = {'10' : 'need1', '11':'need8', '12':'need11', '13':'need1','14':'need3'}
T_SRT = OrderedDict(sorted(T_OLD.items(), key=lambda t: t[0]))
x_val = list(map(int, T_SRT.keys()))
y_val = list(map(lambda x: int(re.findall(r'\d+', x)[-1]), T_SRT.values()))
plt.plot(x_val, y_val,'r')
plt.ylim([0.9*min(y_val),1.1*max(y_val)])
ax = plt.gca()
y_axis = list(set(y_val))
ax.set_yticks(y_axis)
ax.set_yticklabels(['need' + str(i) for i in y_axis])
plt.title('T_OLD')
plt.xlabel('time')
plt.ylabel('need')
plt.show()
此解决方案使用re.findall
查找标签末尾的数字,以适应多位数字的可能性。之前的解决方案只占用了字符串的最后一个部分,因为数字是单个数字。它仍然假设绘制位置的数字是字符串中的最后一个数字,因此[-1]
。再次为Python 3.X映射输出显式转换为list,在Python 2.7中不需要步骤。
现在通过首先使用set
选择唯一的y值,然后通过将字符串'need'
与其对应的整数串联来重命名其标签来生成标签。
y轴的极限设置为最小值的0.9和最大值的1.1。其余格式与以前一样。
此测试用例的结果是: