import oracledb import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 数据库连接信息 dsn = ( "(DESCRIPTION=" "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.164.60)(PORT=1521)))" "(CONNECT_DATA=(SERVICE_NAME=YMSDB01)))" ) username = 'acme' password = 'acme' oracledb.init_oracle_client(lib_dir=r"C:\Users\Q06412\Downloads\instantclient-basic-windows.x64-21.17.0.0.0dbru\instantclient_21_17") # 创建连接 connection = oracledb.connect(user=username, password=password, dsn=dsn) try: # 创建一个游标 cursor = connection.cursor() # SQL 查询语句 sql_query = """ select WAFER_TYPE, LOTNO, T_WAFER_ID,WAFER_NO, MEASURE_TIME, PARAMETER_MAPPING, RANGE_INDEX, SITE_COUNT, AVERAGE, MAX_VAL,MIN_VAL, STD_DEV, SITE1_VAL, SITE2_VAL, SITE3_VAL, SITE4_VAL, SITE5_VAL, SITE6_VAL, SITE7_VAL, SITE8_VAL, SITE9_VAL, SITE10_VAL, SITE11_VAL, SITE12_VAL, SITE13_VAL, SITE14_VAL, SITE15_VAL, SITE16_VAL, SITE17_VAL, SITE18_VAL, SITE19_VAL, SITE20_VAL, SITE21_VAL, SITE22_VAL, SITE23_VAL, SITE24_VAL, SITE25_VAL FROM ACME.DRB_DATA """ # 执行查询 cursor.execute(sql_query) # 获取所有结果 results = cursor.fetchall() columns = [ 'WAFER_TYPE', 'LOTNO', 'T_WAFER_ID', 'WAFER_NO', 'MEASURE_TIME', 'PARAMETER_MAPPING', 'RANGE_INDEX' , 'SITE_COUNT', 'AVERAGE','MAX_VAL','MIN_VAL', 'STD_DEV', 'SITE1_VAL', 'SITE2_VAL', 'SITE3_VAL', 'SITE4_VAL', 'SITE5_VAL', 'SITE6_VAL','SITE7_VAL', 'SITE8_VAL', 'SITE9_VAL', 'SITE10_VAL', 'SITE11_VAL', 'SITE12_VAL', 'SITE13_VAL', 'SITE14_VAL', 'SITE15_VAL', 'SITE16_VAL', 'SITE17_VAL', 'SITE18_VAL', 'SITE19_VAL', 'SITE20_VAL', 'SITE21_VAL', 'SITE22_VAL', 'SITE23_VAL', 'SITE24_VAL', 'SITE25_VAL' ] drbdata = pd.DataFrame(results, columns=columns) data_sorted = drbdata.sort_values(by='MEASURE_TIME') data_sorted['LOT_WAFER'] = data_sorted['LOTNO']+'-'+data_sorted['WAFER_NO'].astype(str) site_columns = [f'SITE{i}_VAL' for i in range(1, 26)] # 宽表转长表 不需要考虑测了多少site,直接按wafer、para分组计算统计量 melted_data = data_sorted.melt( id_vars=['PARAMETER_MAPPING', 'LOT_WAFER', 'WAFER_TYPE'], value_vars=site_columns, var_name='SITE', value_name='VALUE' ) def plot_parameter_boxplots(parameter): # 筛选特定参数的数据 subset = melted_data[melted_data['PARAMETER_MAPPING'] == parameter] # 创建画布 plt.figure(figsize=(15, 6)) # 定义颜色映射规则 palette = { 'DRB_WAFER': '#00FF00', 'NONE_DRB_WAFER': '#FFFF00' } # 绘制箱线图 sns.boxplot( x='LOT_WAFER', y='VALUE', hue='WAFER_TYPE', data=subset, palette=palette, dodge=False # 确保同一T_WAFER_ID不分离显示 ) # 美化图表 plt.title(f'{parameter} - 按晶圆ID分布') plt.xlabel('') plt.ylabel('value') plt.xticks(rotation=45) plt.legend(title='WAFER_TYPE') plt.tight_layout() plt.show() # 遍历所有参数生成图表 for param in melted_data['PARAMETER_MAPPING'].unique(): plot_parameter_boxplots(param) except Exception as e: print(e) finally: # 关闭游标和连接 cursor.close() connection.close() 报错:local variable 'boxprops' referenced before assignment
时间: 2025-06-22 17:30:14 浏览: 15
<think>嗯,用户遇到了一个错误:“local variable 'boxprops' referenced before assignment”,他们希望得到解决。我需要先理解代码的结构以及错误发生的原因。用户提供的代码是使用Python连接Oracle数据库,提取数据后用Seaborn绘制箱线图。看起来问题出在绘图部分。
首先,用户的代码中调用了sns.boxplot,并传入了多个参数,包括palette和dodge。Seaborn的boxplot函数在背后调用了Matplotlib的boxplot,而某些参数可能在传递过程中需要特别处理。根据错误信息,问题出现在'boxprops'变量在赋值前被引用,这说明在Seaborn或Matplotlib的代码中,某个地方尝试使用boxprops变量,但它没有被正确初始化。
查阅Seaborn的文档,发现boxplot函数有一个boxprops参数,用于设置箱体的属性,比如颜色、线宽等。可能用户在代码中没有显式设置这个参数,但Seaborn内部在处理其他参数(比如palette)时,可能在某些情况下未能正确初始化boxprops,导致错误。或者,用户使用的Seaborn版本存在兼容性问题。
另外,用户可能在使用较新或较旧版本的Seaborn,其中某些内部变量的处理方式不同。例如,在旧版本中,如果hue参数与palette一起使用,并且dodge=False,可能导致内部状态不一致,从而引发变量未赋值的错误。
接下来,我需要思考可能的解决方案。首先,可以尝试升级Seaborn和Matplotlib到最新版本,看看问题是否解决。其次,可以显式设置boxprops参数,避免其未被赋值的情况。例如,在sns.boxplot中添加boxprops={},或者根据不同的Wafer类型设置不同的箱体属性。
另外,用户在使用palette参数时,可能希望不同的Wafer_TYPE对应不同的颜色。但设置dodge=False会导致所有箱体在同一位置绘制,而hue分组的颜色可能无法正确应用,这可能导致Seaborn内部处理时出现错误。这时候,可能需要调整dodge参数为True,或者调整数据的分组方式,确保每个箱体有独立的位置,从而正确应用颜色映射。
此外,用户代码中在绘制箱线图时,同一LOT_WAFER下的不同WAFER_TYPE可能会重叠,因为dodge=False。此时,Seaborn可能尝试为每个分组设置不同的颜色,但由于位置未分开,导致内部处理错误。尝试将dodge=True,看看是否能解决问题。如果设置为True,可能需要调整数据或图表布局,避免重叠。
另一个可能性是,某些Wafer_TYPE在数据子集中不存在,导致palette中的颜色映射到不存在的键,从而引发错误。需要检查subset中的WAFER_TYPE是否都包含在palette定义的键中。例如,如果数据中有除了'DRB_WAFER'和'NONE_DRB_WAFER'之外的其他类型,而palette没有定义对应的颜色,可能会导致内部错误。可以通过打印subset['WAFER_TYPE'].unique()来确认。
如果以上方法都无法解决,可能需要查看Seaborn的源代码,找到boxprops被引用的位置,看看在什么情况下会导致未赋值。不过这可能比较复杂。作为替代,可以尝试显式传递boxprops参数,例如:
sns.boxplot(
...,
boxprops=dict(facecolor='...', color='...'),
)
但这里用户使用了hue参数,可能需要根据不同的hue值设置不同的boxprops。这时候可能需要更复杂的处理,比如使用hue后,通过palette参数传递颜色,但需要确保boxprops能正确处理这些颜色。或者,改用Matplotlib的boxplot函数手动绘制,但这会增加代码复杂度。
综合以上分析,可能的解决步骤是:
1. 检查数据中的WAFER_TYPE是否与palette中的键匹配。
2. 尝试将dodge参数设为True,并调整图表布局。
3. 显式设置boxprops参数,避免未赋值的情况。
4. 升级Seaborn和Matplotlib库。
用户遇到的错误可能是在使用旧版Seaborn时,hue和dodge参数的组合导致内部变量未正确初始化。例如,在Seaborn 0.11.2中,当dodge=False且hue分组存在时,可能无法正确生成boxprops,从而引发错误。升级到新版本可能解决此问题。
如果用户无法升级库,可以尝试显式设置boxprops,例如添加boxprops={}到boxplot的参数中,覆盖内部可能存在的未初始化变量。或者,根据Seaborn的版本调整参数。
总结解决方案:建议用户检查数据中的WAFER_TYPE是否与palette一致,调整dodge为True,或者显式设置boxprops。同时,升级库到最新版本可能解决潜在的兼容性问题。</think>这个错误通常发生在Seaborn版本与代码存在兼容性问题时。以下是逐步解决方案:
1. **问题定位**:
错误发生在`sns.boxplot()`绘制过程中,Seaborn内部处理箱线图属性时`boxprops`变量未正确初始化。
2. **直接修复方案**(推荐):
在`boxplot()`调用中显式添加`boxprops`参数:
```python
sns.boxplot(
x='LOT_WAFER',
y='VALUE',
hue='WAFER_TYPE',
data=subset,
palette=palette,
dodge=False,
boxprops={'edgecolor': 'black'} # 添加显式属性设置
)
```
3. **完整修复步骤**:
```python
def plot_parameter_boxplots(parameter):
subset = melted_data[melted_data['PARAMETER_MAPPING'] == parameter]
plt.figure(figsize=(15, 6))
palette = {'DRB_WAFER': '#00FF00', 'NONE_DRB_WAFER': '#FFFF00'}
sns.boxplot(
x='LOT_WAFER',
y='VALUE',
hue='WAFER_TYPE',
data=subset,
palette=palette,
dodge=False,
boxprops={'linewidth': 0.5}, # 显式设置箱线属性
whiskerprops={'color': 'black'},
medianprops={'color': 'red'}
)
plt.title(f'{parameter} - 按晶圆ID分布')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
```
4. **根本原因分析**:
- 当使用`dodge=False`时,Seaborn需要合并不同hue类别的箱线图
- 旧版本(如0.11.x)可能在处理颜色映射时未正确初始化绘图属性
- 显式设置`boxprops`可绕过内部变量初始化问题
5. **附加建议**:
```bash
# 升级库版本(在终端执行)
pip install --upgrade seaborn matplotlib
```
6. **防御性编程改进**:
```python
# 在绘图前添加类型检查
valid_types = subset['WAFER_TYPE'].unique()
if not all(t in palette.keys() for t in valid_types):
raise ValueError("存在未定义颜色的WAFER_TYPE")
```
通过上述修改,即可解决`boxprops`未定义的问题,同时增强代码的健壮性。该问题属于Seaborn库的版本兼容性问题,显式设置绘图属性是最直接的解决方案。
阅读全文
相关推荐



















