You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确缩放cmapcolor使条形颜色匹配色条?

解决cmap颜色与色条不匹配的问题

问题原因

你遇到的颜色不匹配问题,核心是未对Distance值做归一化处理。Matplotlib的颜色映射函数(如cmapz())要求输入参数必须是**[0, 1]区间的数值**,但你的Distance取值范围是0到4,当传入大于1的数值时,会被自动截断为1,导致所有Distance>1的片段都显示色条最右端的颜色(比如plasma的黄色),和色条标注的对应值完全不符。

解决方案

只需要将Distance值归一化到[0,1]区间后,再传入颜色映射函数即可,以下提供两种可行方式:

方式1:使用Normalize类(推荐,更规范)

导入Normalize类,基于Distance的实际取值范围创建归一化对象,统一处理数值映射:

from matplotlib.colors import Normalize

# 基于Distance的最小/最大值创建归一化对象
norm = Normalize(vmin=min(Distanceslst), vmax=max(Distanceslst))

然后在循环生成条形颜色时,用归一化后的值获取颜色:

cmapcolor = cmapz(norm(Distanceslst[i]))

方式2:手动归一化(简单直接)

直接将每个Distance值除以最大值,缩放到[0,1]区间:

max_dist = max(Distanceslst)
cmapcolor = cmapz(Distanceslst[i] / max_dist)

修正后的完整代码

另外注意原代码中templength未定义,这里替换为从数据中获取模板长度,避免报错:

#Create some fake example data and store it in a dataframe
import pandas as pd
import random as rd

exampledf=pd.DataFrame()

tempname='Template'
queryname='Query'

templatenamelst=[]
querynamelst=[]
startlst=[]
endlst=[]
querystartslst=[]
queryendslst=[]
distancelst=[]

for i in range(20):
    start=i*5
    end=(i*5)+25
    distance=rd.uniform(0, 4)
    
    querystart=rd.randint(0, 95)
    queryend=querystart+25
    
    templatenamelst.append(tempname)
    querynamelst.append(queryname)
    startlst.append(start)
    endlst.append(end)
    distancelst.append(distance)
    querystartslst.append(querystart)
    queryendslst.append(queryend)

exampledf['TempName']=templatenamelst
exampledf['QueryName']=querynamelst
exampledf['TempStarts']=startlst
exampledf['TempEnds']=endlst
exampledf['QueryStarts']=querystartslst
exampledf['QueryEnds']=queryendslst
exampledf['Distances']=distancelst

display(exampledf)

    
#Build the plot from the example data
import numpy as np
import warnings
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import Normalize
warnings.filterwarnings('ignore') 

TempName=exampledf.iloc[0]['TempName']
QueryName=exampledf.iloc[0]['QueryName']
NumSeqFrags=len(exampledf)

# 从数据中获取模板长度,替换未定义的templength
TempLength = max(exampledf['TempEnds'])

Distanceslst=list(exampledf.Distances)

XMax=max(list(exampledf.TempEnds))
cmapz = cm.get_cmap('plasma')

# 创建归一化对象
norm = Normalize(vmin=min(Distanceslst), vmax=max(Distanceslst))

img = plt.imshow(np.array([[0,max(Distanceslst)]]), cmap="plasma")
img.set_visible(False)

barheight=6

plt.barh(width=TempLength, left=0, height=barheight, y=0,color='Black')
ticklabels=[TempName]
ticklocations=[0]

#Add the fragments
for i in range (len(exampledf)):
    # 使用归一化后的值获取颜色
    cmapcolor=cmapz(norm(Distanceslst[i]))
    width=int(exampledf.iloc[i]['TempEnds'])-int(exampledf.iloc[i]['TempStarts'])
    start=int(exampledf.iloc[i]['TempStarts'])

    yloc=(barheight+4)*i+barheight

    plt.barh(width=width, left=start, height=barheight, y=yloc,color=cmapcolor)
    
    fullname=str(exampledf.iloc[i]['QueryName'])+'('+str(exampledf.iloc[i]['QueryStarts'])+':'+str(exampledf.iloc[i]['QueryEnds'])+')'+'(Distance='+str(round(Distanceslst[i],2))+')'
    ticklabels.append(fullname)
    ticklocations.append(yloc)

plt.yticks(ticks=ticklocations, labels=ticklabels,fontsize=8)    

plt.colorbar(orientation="horizontal",fraction=0.05,label='Distance')

plt.show() 

效果说明

修改后,每个条形的颜色会根据Distance的实际值,对应色条上的位置显示正确颜色,比如Distance=1.75的片段会显示plasma色条上对应1.75的浅紫色,和色条标注完全匹配。

内容的提问来源于stack exchange,提问作者Jamie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:25:12