我确实有以下数据:
所以:现在我想在x上绘制y1和y2,其中绘图以colorInfo给出的颜色着色
我的数据(我从csv文件中获取)可能如下所示:
tmpSet[8]
所以我希望y1和y2的情节颜色如下:
从-300到-298:蓝色
从-298到-295:蓝色
从-295到-292:红色
现在我有以下代码(基本上是:https://matplotlib.org/1.5.0/examples/pylab_examples/multicolored_line.html的修改版本):
x | y1 | y2 | color
-300 | 50 | 0.5 | 0
-298 | 51 | 0.4 | 0
-295 | 51 | 0.2 | 1
-292 | 44 | 0.1 | 1
最小的csv文件是:
import csv, os
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm
import tkinter as tk
from tkinter import filedialog
def plotter(filepath):
data = read_csv(os.path.abspath(filepath))
x_values = [None if data["x"] is '' else float(data["x"]) for data["x"] in data["x"]]
y1_values = [None if data["y1"] is '' else float(data["y1"]) for data["y1"] in data["y1"]]
y2_values = [None if data["y2"] is '' else float(data["y2"]) for data["y2"] in data["y2"]]
colorInfo = [None if data["color"] is '' else float(data["color"]) for data["color"] in data["color"]]
cmap = ListedColormap(['b', 'r', 'g'])
norm = BoundaryNorm([-1, -0.5, 0.5, 1], cmap.N)
points = np.array([x_values, y1_values]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, cmap=cmap, norm=plt.Normalize(0, 10))
lc.set_array(colorInfo)
lc.set_linewidth(3)
fig1 = plt.figure()
plt.gca().add_collection(lc)
plt.show()
def read_csv(filename):
data = {}
with open(filename) as csvfile:
csvreader = csv.DictReader(csvfile, delimiter=',')
for row in csvreader:
for key in row.keys():
if key not in data:
data[key] = []
data[key].append(row[key])
return data
if __name__ == '__main__':
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
print(file_path)
plotter(file_path)
这只显示白屏。我想我需要lc.set_array。 但我确实遇到的问题是我只能将其设置为函数而不是我定义的点。
有什么建议吗?
答案 0 :(得分:0)
您看到空白图的原因是因为将LineCollection
直接添加到轴不会缩放它,并且默认比例从0到1不包括您的数据。因此,一个立即修复只是在绘图代码末尾的轴上调用autoscale
(参见代码中的注释2)。此外,您不需要传递norm
参数,因为您的颜色信息已经按要求分类(参见代码中的注释1)。您用来阅读csv的代码似乎在我的测试中有效,但是很奇怪并且会破坏您的列表,因此在调用函数后检查data["x"]
只会给出一个值而不是原始列表。
这是一个代码版本,它从包含测试数据的test.csv
文件进行绘图。我已经使用pandas而不是csv模块来阅读,因为它更简洁。
import pandas
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap
df = pandas.read_csv('test.csv')
def colorline(x, y, c):
cmap = ListedColormap(['b', 'r', 'g'])
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
# Note 1: You don't need the norm argument below with your data
lc = LineCollection(segments, cmap=cmap)
lc.set_array(c)
lc.set_linewidth(3)
return lc
fig, ax = plt.subplots(1, 1)
ax.add_collection(colorline(df.x, df.y1, df.color))
ax.add_collection(colorline(df.x, df.y2, df.color))
# Note 2: Adding the line collections directly doesn't cause autoscaling, so you have to call autoscale manually
ax.autoscale()
上面代码生成的图表如下所示: