Python заговор с разными фигурами не удается
РЕДАКТИРОВАТЬ: я понял, что проблема всегда возникает, если кто-то пытается построить два разных списка фигур. Значит ли это, что в одном цикле нельзя создавать графики для разных списков фигур? Смотрите последний код для более простого примера проблемы.
Я пытаюсь проанализировать сложный набор данных, который состоит в основном об измерениях электроприборов в разных условиях. Следовательно, код немного сложнее, но я попытался привести его к рабочему примеру - однако он все еще довольно длинный. Поэтому позвольте мне объяснить, что вы видите: вы видите 3 класса с транзистором, представляющим электронное устройство. Его атрибут Y представляет данные измерений, состоящие из 2 наборов измерений. Каждый транзистор принадлежит группе - 2 в этом примере. И некоторые группы принадлежат к одной и той же серии - одна серия, где обе группы включены в этот пример.
Теперь цель состоит в том, чтобы построить все данные измерений для каждого Транзистора (не показаны), а затем также отобразить все данные, принадлежащие одной и той же группе на одном графике, и все данные одного ряда на одном графике. Чтобы эффективно программировать его без большого количества циклов, моя идея заключалась в том, чтобы использовать объектно-ориентированную природу matplotlib - у меня будут фигуры и субплоты для каждого уровня построения графиков (инициализируются в initGrpPlt и initSeriesPlt), которые затем заполняются только один цикл по всем транзисторам (в MainPlt: toGPlt и toSPlt). В конце это должно только быть напечатано / сохранено в файл / что-нибудь (PltGrp и PltSeries).
Проблема: Несмотря на то, что я указываю, где строить графики, Python выводит графики серии на групповые графики. Вы можете проверить это самостоятельно, запустив код со строкой "toSPlt(trans,j)" и без нее. Я понятия не имею, почему python делает это, потому что в функции toSPlt я явно говорю, что python должен использовать субплоты из списка series-subplot-list. У кого-нибудь есть идея, почему это так и как решить эту проблему изящным образом?
Прочитайте код снизу вверх, это должно помочь в понимании.
С уважением
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
maxNrVdrain = 2
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
A = [[1*np.cos(X),2*np.cos(X),3*np.cos(X),4*np.cos(X)],[1*np.tan(X),2*np.tan(X),3*np.tan(X),4*np.tan(X)]]
B = [[2* np.sin(X),4* np.sin(X),6* np.sin(X),8* np.sin(X)],[2*np.cos(X),4*np.cos(X),6*np.cos(X),8*np.cos(X)]]
class Transistor(object):
_TransRegistry = []
def __init__(self,y1,y2):
self._TransRegistry.append(self)
self.X = X
self.Y = [y1,y2]
self.group = ''
class Groups():
_GroupRegistry = []
def __init__(self,trans):
self._GroupRegistry.append(self)
self.transistors = [trans]
self.figlist = []
self.axlist = []
class Series():
_SeriesRegistry = []
def __init__(self,group):
self._SeriesRegistry.append(self)
self.groups = [group]
self.figlist = []
self.axlist = []
def initGrpPlt():
for group in Groups._GroupRegistry:
for j in range(maxNrVdrain):
group.figlist.append(plt.figure(j))
group.axlist.append(group.figlist[j].add_subplot(111))
return
def initSeriesPlt():
for series in Series._SeriesRegistry:
for j in range(maxNrVdrain):
series.figlist.append(plt.figure(j))
series.axlist.append(series.figlist[j].add_subplot(111))
return
def toGPlt(trans,j):
colour = cm.rainbow(np.linspace(0, 1, 4))
group = trans.group
group.axlist[j].plot(trans.X,trans.Y[j], color=colour[group.transistors.index(trans)], linewidth=1.5, linestyle="-")
return
def toSPlt(trans,j):
colour = cm.rainbow(np.linspace(0, 1, 2))
series = Series._SeriesRegistry[0]
group = trans.group
if group.transistors.index(trans) == 0:
series.axlist[j].plot(trans.X,trans.Y[j],color=colour[series.groups.index(group)], linewidth=1.5, linestyle="-", label = 'T = nan, RH = nan' )
else:
series.axlist[j].plot(trans.X,trans.Y[j],color=colour[series.groups.index(group)], linewidth=1.5, linestyle="-")
return
def PltGrp(group,j):
ax = group.axlist[j]
ax.set_title('Test Grp')
return
def PltSeries(series,j):
ax = series.axlist[j]
ax.legend(loc='upper right', frameon=False)
ax.set_title('Test Series')
return
def MainPlt():
initGrpPlt()
initSeriesPlt()
for trans in Transistor._TransRegistry:
for j in range(maxNrVdrain):
toGPlt(trans,j)
toSPlt(trans,j)#plots to group plot for some reason
for j in range(maxNrVdrain):
for group in Groups._GroupRegistry:
PltGrp(group,j)
plt.show()
return
def Init():
for j in range(4):
trans = Transistor(A[0][j],A[1][j])
if j == 0:
Groups(trans)
else:
Groups._GroupRegistry[0].transistors.append(trans)
trans.group = Groups._GroupRegistry[0]
Series(Groups._GroupRegistry[0])
for j in range(4):
trans = Transistor(B[0][j],B[1][j])
if j == 0:
Groups(trans)
else:
Groups._GroupRegistry[1].transistors.append(trans)
trans.group = Groups._GroupRegistry[1]
Series._SeriesRegistry[0].groups.append(Groups._GroupRegistry[1])
return
def main():
Init()
MainPlt()
return
main()
последний пример, который не работает:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
Y1 = np.cos(X)
Y2 = np.sin(X)
figlist1 = []
figlist2 = []
axlist1 = []
axlist2 = []
for j in range(4):
figlist1.append(plt.figure(j))
axlist1.append(figlist1[j].add_subplot(111))
figlist2.append(plt.figure(j))#this should be a new set of figures!
axlist2.append(figlist2[j].add_subplot(111))
colour = cm.rainbow(np.linspace(0, 1, 4))
axlist1[j].plot(X,j*Y1, color=colour[j], linewidth=1.5, linestyle="-")
axlist1[j].set_title('Test Grp 1')
colour = cm.rainbow(np.linspace(0, 1, 4))
axlist2[j].plot(X,j*Y2, color=colour[int(j/2)], linewidth=1.5, linestyle="-")
axlist2[j].set_title('Test Grp 2')
plt.show()
1 ответ
Хорошо, глупая ошибка, если кто-то думает о Фоне, но, возможно, у кого-то есть подобная Проблема и он не может увидеть причину, как я был первым. Итак, вот решение:
Проблема в том, что имена объектов-списков, таких как figlist1[j], не определяют фигуру - они всего лишь указатели на фактический объект фигуры. и если такой объект создается с помощью plt.figure (j), необходимо убедиться, что j отличается для каждой фигуры - следовательно, в цикле, где нужно инициализировать несколько фигур, нужно как-то изменить номер фигуры или первый объект будет перезаписан. Надеюсь, это поможет! Приветствия.