Python 绘制不同的图形失败
Python plotting to different figures fails
编辑:我发现如果试图绘制两个不同的数字列表,问题总是会发生。这是否意味着不能在同一个循环中绘制不同的图形列表?有关更简单的问题示例,请参阅最新代码。
我尝试分析一组复杂的数据,这些数据基本上由不同条件下电子设备的测量值组成。因此,代码有点复杂,但我试图将其简化为一个工作示例——但它仍然很长。因此,让我解释一下你看到了什么:你看到 3 类 晶体管代表电子设备。它的属性 Y 代表测量数据——由 2 组测量值组成。每个晶体管都属于一个组 - 在本例中为 2 个。并且一些组属于同一个系列——一个系列,其中两个组都包含在此示例中。
现在的目标是绘制每个晶体管(未显示)的所有测量数据,然后将属于同一组的所有数据绘制在一个图中,每个数据和所有数据同一系列到一个地块。为了以一种有效的方式对其进行编程而没有很多循环,我的想法是使用 matplotlib 的面向对象的特性——我将为每个绘图级别(在 initGrpPlt 和 initSeriesPlt 中初始化)提供图形和子图,然后用所有晶体管只有一个循环(在 MainPlt 中:toGPlt 和 toSPlt)。最后它应该只被打印/保存到一个文件/任何(PltGrp 和 PltSeries)。
问题: 即使我指定了绘制位置,python 还是将系列图绘制到组图中。您可以通过 运行 包含 'toSPlt(trans,j)' 行和不包含行的代码自行检查。我不知道为什么 python 这样做,因为在函数 toSPlt 中我明确地说 python 应该使用系列子图列表中的子图。有谁知道为什么会这样以及如何以优雅的方式解决这个问题?
从下往上阅读代码,应该有助于理解。
亲切的问候
# -*- 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()
好吧,如果有人想到背景,这是愚蠢的错误,但也许有人有类似的问题并且无法像我第一次那样看到原因。所以这是解决方案:
问题是像 figlist1[j] 这样的列表对象的名称没有定义图形 - 它们只是指向实际图形对象的指针。并且如果这样的对象是由 plt.figure(j) 创建的,则必须确保每个图形的 j 不同 - 因此,在一个循环中,多个图形应被初始化,需要以某种方式更改图形的编号否则第一个对象将被覆盖。希望有帮助!干杯。
编辑:我发现如果试图绘制两个不同的数字列表,问题总是会发生。这是否意味着不能在同一个循环中绘制不同的图形列表?有关更简单的问题示例,请参阅最新代码。
我尝试分析一组复杂的数据,这些数据基本上由不同条件下电子设备的测量值组成。因此,代码有点复杂,但我试图将其简化为一个工作示例——但它仍然很长。因此,让我解释一下你看到了什么:你看到 3 类 晶体管代表电子设备。它的属性 Y 代表测量数据——由 2 组测量值组成。每个晶体管都属于一个组 - 在本例中为 2 个。并且一些组属于同一个系列——一个系列,其中两个组都包含在此示例中。
现在的目标是绘制每个晶体管(未显示)的所有测量数据,然后将属于同一组的所有数据绘制在一个图中,每个数据和所有数据同一系列到一个地块。为了以一种有效的方式对其进行编程而没有很多循环,我的想法是使用 matplotlib 的面向对象的特性——我将为每个绘图级别(在 initGrpPlt 和 initSeriesPlt 中初始化)提供图形和子图,然后用所有晶体管只有一个循环(在 MainPlt 中:toGPlt 和 toSPlt)。最后它应该只被打印/保存到一个文件/任何(PltGrp 和 PltSeries)。
问题: 即使我指定了绘制位置,python 还是将系列图绘制到组图中。您可以通过 运行 包含 'toSPlt(trans,j)' 行和不包含行的代码自行检查。我不知道为什么 python 这样做,因为在函数 toSPlt 中我明确地说 python 应该使用系列子图列表中的子图。有谁知道为什么会这样以及如何以优雅的方式解决这个问题?
从下往上阅读代码,应该有助于理解。
亲切的问候
# -*- 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()
好吧,如果有人想到背景,这是愚蠢的错误,但也许有人有类似的问题并且无法像我第一次那样看到原因。所以这是解决方案:
问题是像 figlist1[j] 这样的列表对象的名称没有定义图形 - 它们只是指向实际图形对象的指针。并且如果这样的对象是由 plt.figure(j) 创建的,则必须确保每个图形的 j 不同 - 因此,在一个循环中,多个图形应被初始化,需要以某种方式更改图形的编号否则第一个对象将被覆盖。希望有帮助!干杯。