从多个数组中绘制数据时,将线条颜色与图例匹配 [英] matching line colors to legend when plotting data from multiple arrays

查看:75
本文介绍了从多个数组中绘制数据时,将线条颜色与图例匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有来自不同板上的多个设备的温度数据,例如,在板上1,我具有PCB本身,3个不同的FET的温度,以及板上2和3的温度. 我将数据读入一个数据帧,并希望以相同的颜色为测试的每个电路板绘制数据,但为电路板上的每个设备使用不同的标记.例如,板1的所有测量结果均为蓝色,PCB温度使用标记"+",FET1使用标记"v"等.
我这样读取文件:

I have temperature data from multiple devices on different boards, for example, on board 1 I have temperature for the PCB itself, and 3 different FETs, and similarly for boards 2 and 3. I read the data into a dataframe, and want to plot the data together with the same color for each board tested, but with different markers for each of the devices on the boards. For example, all the measurements from board 1 would be blue, with the PCB temp using marker '+', FET1 using marker 'v' etc.
I read the files in like this:

for file_name in glob.glob(path+'*.csv'):
    filename[i] = os.path.basename(file_name)
    print(filename[i])
    #x[i]= np.genfromtxt(path+ filename[i], delimiter=',',skip_header=20,usecols=(2,4,6,8))
    x[i]=pd.read_csv(path+filename[i], header=0,usecols=[2,4,6,8], skiprows=12,names=['PCB', 'FET1', 'FET2', 'FET3'])

并创建一个数据框数组.

and create an array of dataframes.

然后绘制不同的列:

colors=['r','b','g','c','m']
for i in range(len(filename)):
    #plt.figure()
    plt.plot(sc.decimate(x[i]['PCB'],5),'-+'+colors[i],label="PCB")
    plt.plot(sc.decimate(x[i]['FET1'],5),'-v'+colors[i],label='FET1')
    plt.plot(sc.decimate(x[i]['FET2'],5),'-x'+colors[i],label='FET2')
    plt.plot(sc.decimate(x[i]['FET3'],5),'-o'+colors[i],label='FET3')
    leg=np.append(leg, filename[i][0:7])
    #plt.show()


plt.show()
plt.legend(leg)

标记正确显示,但是当我遍历数据框时,颜色信息丢失了.如何绘制数据并进行排列,以使图例每组线使用相同的颜色(按索引i分组)?

The markers are correctly displayed, but as I iterated through the dataframes, the color information was lost. How can I plot the data and arrange it so that legend uses the same color per group of lines (as grouped by index i)?

以下是一些示例数据: 文件1:

Here's some sample data: file 1:

Name:,Data Instr INSTR 3/5/2020 11:51:59,,,,,,,,,,,,
Owner:,lab1,,,,,,,,,,,,
Comments:,,,,,,,,,,,,,
Acquisition Date:,3/5/2020 11:51,,,,,,,,,,,,
&Instrument:,34970A,Address:,ASRL11::INSTR,Modules:,1,Slot3:,34901A,,,,,,
Total Channels:,4,,,,,,,,,,,,
Channel,Name,Function,Range,Resolution,AdvSettings,Scale,Gain,Offset,Label,Test,Low,High,HWAlarm
316,PCB_CTR,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
317,Q24,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
318,Q25,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
319,Q18,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
Scan  Control:,Start Action:,Immediately,Stop Action:,User Terminated,,,,,,,,,
Scan,Time,316 <PCB_CTR> (C),Alarm 316,317 <Q24> (C),Alarm 317,318 <Q25> (C),Alarm 318,319 <Q18> (C),Alarm 319,,,,
1,3/5/2020 11:51:59:168,30.471,0,29.241,0,29.165,0,33.302,0,,,,
2,3/5/2020 11:52:01:152,32.197,0,30.634,0,30.564,0,34.819,0,,,,
3,3/5/2020 11:52:03:152,33.795,0,32.019,0,31.879,0,36.848,0,,,,
4,3/5/2020 11:52:05:152,35.315,0,33.383,0,33.236,0,38.282,0,,,,
5,3/5/2020 11:52:07:152,36.965,0,34.734,0,34.62,0,39.946,0,,,,
6,3/5/2020 11:52:09:152,38.255,0,36.054,0,35.776,0,41.18,0,,,,
7,3/5/2020 11:52:11:152,39.467,0,37.328,0,37.028,0,42.258,0,,,,

文件2

Name:,Data Instr INSTR 3/5/2020 10:03:21,,,,,,,,,,,,
Owner:,lab1,,,,,,,,,,,,
Comments:,,,,,,,,,,,,,
Acquisition Date:,3/5/2020 10:03,,,,,,,,,,,,
&Instrument:,34970A,Address:,ASRL11::INSTR,Modules:,1,Slot3:,34901A,,,,,,
Total Channels:,4,,,,,,,,,,,,
Channel,Name,Function,Range,Resolution,AdvSettings,Scale,Gain,Offset,Label,Test,Low,High,HWAlarm
316,PCB_CTR,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
317,Q24,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
318,Q25,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
319,Q18,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
Scan  Control:,Start Action:,Immediately,Stop Action:,User Terminated,,,,,,,,,
Scan,Time,316 <PCB_CTR> (C),Alarm 316,317 <Q24> (C),Alarm 317,318 <Q25> (C),Alarm 318,319 <Q18> (C),Alarm 319,,,,
1,3/5/2020 10:03:21:164,46.334,0,43.755,0,45.706,0,49.129,0,,,,
2,3/5/2020 10:03:22:149,46.997,0,44.262,0,46.35,0,49.773,0,,,,
3,3/5/2020 10:03:23:149,47.615,0,44.671,0,46.974,0,50.402,0,,,,
4,3/5/2020 10:03:24:149,48.267,0,45.229,0,47.628,0,50.879,0,,,,
5,3/5/2020 10:03:25:149,48.861,0,45.711,0,48.164,0,51.495,0,,,,
6,3/5/2020 10:03:26:149,49.455,0,46.323,0,48.783,0,51.9,0,,,,
7,3/5/2020 10:03:27:149,50.014,0,46.796,0,49.351,0,52.334,0,,,,

文件3

Name:,Data Instr INSTR 3/5/2020 13:41:06,,,,,,,,,,,,
Owner:,lab1,,,,,,,,,,,,
Comments:,,,,,,,,,,,,,
Acquisition Date:,3/5/2020 13:41,,,,,,,,,,,,
&Instrument:,34970A,Address:,ASRL11::INSTR,Modules:,1,Slot3:,34901A,,,,,,
Total Channels:,4,,,,,,,,,,,,
Channel,Name,Function,Range,Resolution,AdvSettings,Scale,Gain,Offset,Label,Test,Low,High,HWAlarm
316,PCB_CTR,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
317,Q24,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
318,Q25,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
319,Q18,Temp (Type K),None,C,Temp (Type K)#1#0.016#Auto#0.001#C#Internal#0#false,FALSE,1,0,C,High Only,0,105,Alarm 1
Scan  Control:,Start Action:,Immediately,Stop Action:,User Terminated,,,,,,,,,
Scan,Time,316 <PCB_CTR> (C),Alarm 316,317 <Q24> (C),Alarm 317,318 <Q25> (C),Alarm 318,319 <Q18> (C),Alarm 319,,,,
1,3/5/2020 13:41:06:162,28.121,0,26.882,0,28.785,0,31.061,0,,,,
2,3/5/2020 13:41:08:147,30.582,0,27.873,0,30.691,0,33.024,0,,,,
3,3/5/2020 13:41:10:147,31.782,0,28.935,0,32.578,0,34.876,0,,,,
4,3/5/2020 13:41:12:147,34.003,0,30.094,0,34.247,0,36.652,0,,,,
5,3/5/2020 13:41:14:147,35.097,0,31.199,0,35.975,0,38.142,0,,,,
6,3/5/2020 13:41:16:147,36.708,0,32.334,0,37.504,0,39.721,0,,,,
7,3/5/2020 13:41:18:147,38.274,0,33.508,0,39.048,0,41.198,0,,,,

谢谢您的帮助.

编辑

在@ ilke444的输入帮助下,我离想要的东西越来越近,但是仍然有问题:

With the help from @ilke444's input, I got closer to what I want, but I still have issues:

for i in range(len(filename)):
    l=plt.plot(sc.decimate(x[i]['PCB'],5),'-+'+colors[i],label="PCB")
    lines=np.append(lines,l[0].get_label())
    l=plt.plot(sc.decimate(x[i]['FET1'],5),'-v'+colors[i],label='FET1')
    lines=np.append(lines,l[0].get_label())
    l=plt.plot(sc.decimate(x[i]['FET2'],5),'-x'+colors[i],label='FET2')
    lines=np.append(lines,l[0].get_label())
    l=plt.plot(sc.decimate(x[i]['FET3'],5),'-o'+colors[i],label='FET3')
    lines=np.append(lines,l[0].get_label())

    linesclr=np.append(linesclr, l)  # save color info
    names = np.append(names, filename[i][0:7])

fig.legend(lines, loc=1)
fig.legend(linesclr, labels=names, loc=2)
plt.show()

如下所示,我尝试添加的第二个图例显示的颜色不正确,即每个文件读取一种颜色(左上角):

As can be seen below, the second legend I'm trying to add does not show the right colors, ie, 1 color per file read (top left corner):

我不明白为什么左边的图例没有显示正确的颜色,因为颜色信息包含在lineslr数组的每个元素中:

I don't understand why the legend on the left doesn't show the right colors, since the color information is in each of the elements in the lineslr array:

linesclr[0].get_color()
Out[4]: 'r'
linesclr[0].get_color()
Out[5]: 'r'
linesclr[1].get_color()
Out[6]: 'b'
linesclr[2].get_color()
Out[7]: 'g'

此外,我不明白为什么标记不总是该图例中所有键的圆圈('o').

Furthermore, I don't understand why the marker is not always the circle ('o') for all the keys in that legend.

我正在寻找的解决方案:

Solution I'm looking for:

在我看来,传达情节信息的最佳方法是使用2个图例,但右侧的图例仅显示每种设备类型的每行标记(带有相应标记的黑线),左侧的图例显示文件名和用于该文件中所有温度读数的颜色(无标记的行).

It occurs to me that the best way to convey the info on the plots is with the 2 legends, but with the legend on the right just showing the markers for each line for each device type (black line with corresponding marker), and the legend on the left showing the filenames and the colors (line with no markers) used for all the temperatures readings from that file.

因此,我想在右侧显示图例,仅显示4个热电偶位置及其标记:

So, I'd like to make the legend on the right just show the 4 thermocouple locations with their markers:

+ PCB
v FET1 
x FET2 
o FET3

和左边的图例显示:红色的ACI50#5,蓝色的ACI50#6,绿色的ACI50#6,青色的KDE5515(或我读过的很多文件,每个文件都有其对应的绘图颜色).

and the legend on the left to show: ACI50#5 in red, ACI50# in blue, ACI50#6 in green, an KDE5515 in cyan (or however many files I read in, each with its corresponding plot color).

我曾尝试在matplotlib上阅读传说和撰写自定义传说,并在互联网上寻找示例,但在理解所阅读的内容方面并没有取得多少成功!

I've tried reading and literature on matplotlib on legends and composing custom legends, and have looked for examples on the internet, but I'm not having much success understanding what I'm reading!

推荐答案

我希望这是您正在寻找的:)

I hope this is what you are looking for :)

我认为有两种解决方案是可能的:

I think 2 solutions are possible:

预先,对不起,我不得不模拟数据,所以绘图看起来不像有序线,但是我认为这没问题

In advance, sorry I had to sim data so the plot does not look like ordered lines but I think it is no problem anyway

  1. 所有文件都有一个图例:

import glob
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import scipy.signal as sc
import numpy as np

dfs = [] # store df
cmap = cm.get_cmap('Set1')
cols = {}

for i, fn in enumerate(glob.glob("*.csv")) :
    #dfs.append(pd.read_csv(fn, header=0, usecols=[2,4,6,8], skiprows=12, names=['PCB', 'FET1', 'FET2', 'FET3'])) # Uncommenting this line to read from your files should work
    dfs.append(pd.DataFrame(np.random.randn(100, 4), columns=['PCB', 'FET1', 'FET2', 'FET3'])) # Just random data
    cols[i] = cmap(i) # Maps one color to one file with a dict

mrks = {"PCB":'+',"FET1":'v',"FET2":'x',"FET3":'o'} # Maps one sensor to one marker type

fig, ax = plt.subplots(figsize=(12,12))
for n, d in enumerate(dfs) :
    ax.plot(sc.decimate(d['PCB'],5), ls='-', marker=mrks['PCB'], color=cols[n], label="PCB") # Use label to map to files
    ax.plot(sc.decimate(d['FET1'],5), ls='-', marker=mrks['FET1'], color=cols[n], label="FET1")
    ax.plot(sc.decimate(d['FET2'],5), ls='-', marker=mrks['FET2'], color=cols[n], label="FET2")
    ax.plot(sc.decimate(d['FET3'],5), ls='-', marker=mrks['FET3'], color=cols[n], label="FET3")

ax.legend()
plt.show()

给出该图:

  1. 图例分开(很抱歉,在我的示例中,我交换了位置,但您可以轻松调整它

import glob
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import scipy.signal as sc
import numpy as np
from matplotlib.lines import Line2D

# create a marker for each thermocouple
mrks = {"PCB":'+',"FET1":'v',"FET2":'x',"FET3":'o'}
marker_legend = [Line2D([0], [0], lw=1, color="k", marker=v, label=k) for k, v in mrks.items()]
color_legend = []

dfs = [] # store df
cmap = cm.get_cmap('Set1')
cols = {}
for i, fn in enumerate(glob.glob("*.csv")) : # read files and map colors to each
    #dfs.append(pd.read_csv(fn, header=0, usecols=[2,4,6,8], skiprows=12, names=['PCB', 'FET1', 'FET2', 'FET3']))
    dfs.append(pd.DataFrame(np.random.randn(100, 4), columns=['PCB', 'FET1', 'FET2', 'FET3']))
    cols[i] = cmap(i)
    color_legend.append(Line2D([0], [0], color=cmap(i), lw=1, label=fn))

fig, ax = plt.subplots(figsize=(12,12))
for n, d in enumerate(dfs) :
    ax.plot(sc.decimate(d['PCB'],5), ls='-', marker=mrks['PCB'], color=cols[n])
    ax.plot(sc.decimate(d['FET1'],5), ls='-', marker=mrks['FET1'], color=cols[n])
    ax.plot(sc.decimate(d['FET2'],5), ls='-', marker=mrks['FET2'], color=cols[n])
    ax.plot(sc.decimate(d['FET3'],5), ls='-', marker=mrks['FET3'], color=cols[n])

first_legend = plt.legend(handles=marker_legend, loc="upper left")
ax = plt.gca().add_artist(first_legend)
second_legend = plt.legend(handles=color_legend, loc="upper right")

plt.show()

这是结果图:

如果您不想使用来自matplotlib的cmap,您仍然可以创建一个颜色列表,该列表将比您将读取并从中绘制的文件数量更长,而不是像这样:

If you do not want to use a cmap from matplotlib you can still create a list of colors that you know will be longer than the number of files you will read and draw from it instead something like:

cmap = ["r","g","b","cyan", ...]
...
for i, fn in enumerate(glob.glob("*.csv")) :
   ...
   cols[i] = cmap[i]
   ...

这篇关于从多个数组中绘制数据时,将线条颜色与图例匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆