[英]Python error in plots hierarchy : TypeError: unhashable type: 'list'
我正在為我的樣式圖開發產品的類層次結構,這對於我的目的很有用,
當我嘗試從子類實例化繪圖時,我收到了標題為TypeError: unhashable type: 'list'
的錯誤報告,為了簡化錯誤,我簡化了該類,但是可以使用和測試這些類,尤其是僅當我嘗試從子類調用時,才收到此錯誤,在我未獲得的頂級調用中,現在生成了圖,現在讓我報告幾個類:
層次結構以抽象類開始:
from abc import ABCMeta, abstractmethod
import matplotlib.pyplot as plt
import numpy as np
from abc import ABCMeta, abstractmethod
from cycler import cycler
class BasePlot(metaclass=ABCMeta):
def __init__(self, title : str = ' ' , filename : str = ' '):
self.title = title
self.filename = filename
def schemes(self, style:str = 'nb'):
color = {}
color['nb'] = ['#8DA0CB', '#E58AC3', '#A6D853', '#FFD930', '#B2B2B2', '#5FC3A4', '#FC8D62', '#66C2A5']
return color[style]
def linestyles(self, style : str = 'ls1'):
linestyles = {}
linestyles['paper'] = [(0, ()), (0, (3, 1, 1, 1, 1, 1)), (0, (5, 5)),(0, (5, 1)),(0, (3, 5, 1, 5)),(0, (3, 5, 1, 5, 1, 5)),(0, (1, 1)),(0, (5, 10)) ]
return linestyles[style]
@abstractmethod
def style(self,*args,**kwargs):
pass
從這個基類繼承了一個幾乎定義了我需要的所有東西的類,它被命名為產生默認圖的默認類!
class DefaultPlot(BasePlot) :
def __init__(self, figsize,*args,**kwargs):
self.var = [*args]
self.params = kwargs
def style(self,*args):
self.variable = [*args]
def cycle(self,n : str):
if n == '0':
return plt.cycler("color", self.parameters['scheme']) #colors)
elif n=='1':
return plt.cycler("color", self.parameters['scheme']) + plt.cycler("linestyles", self.parameters['linestyles'])
def setparams(self, kwargs):
self.parameters = kwargs
if 'scheme' in self.parameters.keys():
v = self.parameters['scheme']
self.parameters['scheme'] = self.schemes(v)
if 'font' not in self.parameters.keys():
self.parameters['font'] = 'serif'
if 'scheme' not in self.parameters.keys():
self.parameters['scheme'] = self.schemes('nb')
if 'cycle' not in self.parameters.keys():
self.parameters['cycle'] = self.cycle('0')
if 'linestyles' not in self.parameters.keys():
self.parameters['linestyles'] = self.linestyles('paper')
myparams = {
'axes.prop_cycle': self.parameters['cycle'],
'grid.color' : 'gray',
'font.family': self.parameters['font'] ,
'font.style' : 'italic'
}
plt.rcParams.update(myparams)
def __call__ (self,nrows,ncols,*args,**kwargs):
self.style(*args)
self.setparams(kwargs)
if nrows == ncols ==1:
self.fig, self.axs = plt.subplots(nrows,ncols,figsize=(9.5,4.5))
else:
self.fig, self.axs = plt.subplots(nrows,ncols,figsize=(12,6))
for i in range(nrows):
for j in range(ncols):
if nrows == ncols == 1:
self.axs.set_title('', color='#555555')
legend = leg = self.axs.legend()
else:
self.axs[i,j].set_title('', color='#555555')
legend = leg = self.axs[i,j].legend()
legend.get_frame().set_linewidth(1.2)
plt.setp(legend.get_texts(), color='#555555')
if nrows == ncols ==1 :
plt.subplots_adjust(left=0.125 , bottom=0.125, right=0.95, top=0.87, wspace=0, hspace=0)
else:
plt.subplots_adjust(left=0.06 , bottom=0.1, right=0.95, top=0.95, wspace=0.2, hspace=0.4)
return self.fig,self.axs
最后,我繼承了最后一個級別的類,該類的目的(即使在這里看起來也不是)是替換上面的默認類中定義的參數,以便創建這樣的幾個類來生成樣式圖(基本上在這個類中我替換了顏色..字體的刻度等)
class Standard(DefaultPlot):
def __init__(self , figsize , *args , **kwargs):
self.args = [*args]
self.params = kwargs
super().__init__(figsize,*self.args, **self.params )
def setparams(self, kwargs):
self.parameters = kwargs
if 'scheme' in self.parameters.keys():
v = self.parameters['scheme']
self.parameters['scheme'] = self.schemes(v)
if 'linestyles' not in self.parameters.keys():
self.parameters['linestyles'] = self.linestyles('paper')
if 'scheme' not in self.parameters.keys():
self.parameters['scheme'] = self.schemes('nb')
if 'cycle' not in self.parameters.keys():
self.parameters['cycle'] = self.cycle('0')
super().setparams(self.parameters)
從主腳本調用該類:
import numpy as np
import matplotlib.pyplot as plt
#import defaultplot
import qualityplot
def main():
x = np.linspace(0,2*np.pi,50)
y = np.sin(x)
fig,axs = qualityplot.Standard(figsize=(9.5,4.5))(1,1,**{'scheme':'nb'})
#fig,axs = defaultplot.DefaultPlot(figsize=(9.5,4.5))(1,1,**{'scheme':'nb'})
axs.plot(x,y)
plt.show()
現在,如果您嘗試運行並調用qualityplot,則會收到以下錯誤消息: TypeError: unhashable type: 'list'
但是如果您調用頂級defaultpolot.DefaultPlot(最后一條注釋行),一切就正常了! 我不知道我錯了! 我該如何修理?
該錯誤告訴您不能將列表用作字典鍵。 即以下是不可能在python中
a = {[1,2,3] : "A"}
在您的代碼中會發生此問題,因為您更改了self.parameters['scheme']
的類型。 它可能首先是字符串,然后在以下代碼中轉到列表。
self.parameters = kwargs
if 'scheme' in self.parameters.keys():
v = self.parameters['scheme']
self.parameters['scheme'] = self.schemes(v)
現在,這是super方法中的第二次調用,其中self.parameters['scheme']
已經是列表。 在這種情況下, self.schemes(list)
無效,將導致錯誤。
在schemes
函數中,將color ['nb']設置為列表。
在Standard.setparams
函數中,將此列表放入self.parameters['scheme']
然后調用DefaultPlot.setparams
在DefaultPlot.setparams
,調用v等於此列表的BasePlot.schemes(v)
在BasePlot.schemes
您調用的return color[style]
的樣式等於此列表的樣式,該樣式不起作用(樣式應為字符串)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.