сопоставление цветов линии и легенды при построении данных из нескольких массивов - PullRequest
0 голосов
/ 09 марта 2020

У меня есть данные о температуре от нескольких устройств на разных платах, например, на плате 1 У меня есть температура для самой печатной платы и 3 разных полевых транзистора, и аналогично для плат 2 и 3. Я считываю данные в информационный кадр, и хотите отобразить данные вместе с одинаковым цветом для каждой протестированной платы, но с разными маркерами для каждого из устройств на платах. Например, все измерения на плате 1 будут синего цвета, при этом температура печатной платы будет равна маркеру «+», а FET1 - маркеру v и c.
Я читаю файлы следующим образом:

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'])

и создайте массив данных.

Затем я строю различные столбцы:

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)

enter image description here

Маркеры правильно отображаются, но когда я перебрал кадры данных, информация о цвете была потеряна. Как я могу построить данные и расположить их так, чтобы в легенде использовался один и тот же цвет для каждой группы линий (сгруппированных по индексу i)?

Вот некоторые примеры данных: файл 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 я приблизился к тому, что хочу, но у меня все еще есть проблемы:

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()

Как видно ниже, вторая легенда, которую я пытаюсь добавить, не отображает правильные цвета, ie, 1 цвет на чтение файла (верхний левый угол):

enter image description here

Я не понимаю, почему легенда слева не показывает правильные цвета, так как информация о цвете содержится в каждом из элементов в массиве lineslr:

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') для всех ключей в этой легенде.

Решение, которое я ищу:

Мне приходит в голову, что лучший способ передать информацию на графиках - это две легенды, но с легендой справа, просто показывающей маркеры для каждой строки для ea тип устройства ch (черная линия с соответствующим маркером) и легенда слева, показывающая имена файлов и цвета (строка без маркеров), используемые для всех значений температуры из этого файла.

Итак, я бы хотел, чтобы легенда справа показала 4 местоположения термопар с их маркерами:

+ PCB
v FET1 
x FET2 
o FET3

и легенду слева, чтобы показать: ACI50 # 5 красным, ACI50 # синим, ACI50 # 6 зеленым, KDE5515 синим (или сколько угодно файлов, в которых я читаю, каждый со своим соответствующим цветом графика).

Я пробовал читать и литературу по matplotlib по легендам и составлять собственные легенды, и искал примеры для inte rnet, но у меня не было большого успеха в понимании того, что я читаю!

Ответы [ 2 ]

1 голос
/ 16 марта 2020

Надеюсь, это то, что вы ищете:)

Я думаю, что возможны 2 решения:

Заранее, извините, мне пришлось смоделировать данные, чтобы сюжет не выглядел как упорядоченный линий, но я думаю, что в любом случае это не проблема

  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()

Дает этот график:

One legend for whole data

С разделенными легендами (извините, в моем примере я поменялся местами, но вы можете легко настроить его
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()

Это результирующий график:

Separated legends

Если вы не хотите использовать cmap из matplotlib, вы все равно можете создать список цветов, который, как вы знаете, будет длиннее, чем количество файлов, которые вы прочитаете, и вместо этого будет рисовать что-то вроде :

cmap = ["r","g","b","cyan", ...]
...
for i, fn in enumerate(glob.glob("*.csv")) :
   ...
   cols[i] = cmap[i]
   ...
1 голос
/ 09 марта 2020

Каждый график, нарисованный одним и тем же вызовом в l oop, переписывает легенду, даже если данные разные. Таким образом, вам нужно сохранить их, а затем добавить их в легенду, если перезапись невозможна.

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

fig.legend(lines)
plt.show()

Это обеспечит легенду размера len(filename)*4 с чередующимися цветами. Если вы хотите задать только цвета для файла, вы можете сохранить одну строку на i.

fig = plt.figure()
lines = []
names = []
colors=['r','b','g','c','m']
for i in range(len(filename)):
    l=plt.plot(sc.decimate(x[i]['PCB'],5),'-+'+colors[i],label="PCB")
    lines=np.append(lines,l)
    names=np.append(names, filename[i][0:7])
    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')

fig.legend(lines,labels=names)
plt.show()

РЕДАКТИРОВАТЬ: В качестве третьего варианта вы также можете напрямую сохраните маркеры легенды для коллекции первой строки и установите их позже. Чтобы это работало правильно, вам нужно настроить других так, чтобы у них не было легенды. Предполагая, что вы все равно не отображаете эти метки на графике, это тоже вариант.

lines = []
names = []
colors=['r','b','g','c','m']
for i in range(len(filename)):
    plt.plot(sc.decimate(x[i]['PCB'],5),'-+'+colors[i],label="PCB")
    handles, labels = plt.gca().get_legend_handles_labels()
    lines=np.append(lines,handles[0])
    names=np.append(names, filename[i][0:7])
    plt.plot(sc.decimate(x[i]['FET1'],5),'-v'+colors[i],label='_nolegend_')
    plt.plot(sc.decimate(x[i]['FET2'],5),'-x'+colors[i],label='_nolegend_')
    plt.plot(sc.decimate(x[i]['FET3'],5),'-o'+colors[i],label='_nolegend_')

plt.legend(lines,labels=names)
plt.show()
...