Python matplotlib:在数据坐标中设置colorbar位置

8 投票
2 回答
5103 浏览
提问于 2025-04-18 01:20

我想在散点图里面放一个颜色条,并且希望能通过数据坐标来指定它的位置。这里有个例子,展示了如何通过图形坐标来实现这个功能:

import numpy as np
import matplotlib.pyplot as plt    

#Generate some random data:
a = -2
b = 2
x = (b - a) * np.random.random(50) + a
y = (b - a) * np.random.random(50) + a
z = (b) * np.random.random(50)

#Do a scatter plot
fig = plt.figure()
hdl = plt.scatter(x,y,s=20,c=z,marker='o',vmin=0,vmax=2)
ax = plt.gca()
ax.set_xlim([-2,2])
ax.set_ylim([-2,2])

#Specifying figure coordinates works fine:
fig_coord = [0.2,0.8,0.25,0.05]
cbar_ax = fig.add_axes(fig_coord)

clevs = [0, 1 , 2]
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs)

plt.show()

...好吧,我不能在这里放图,因为我的声望不够。但上面的代码可以让你大概明白效果是什么样的....

现在的问题是,我该如何在数据坐标中放置颜色条,比如说:左边、底部、宽度和高度分别是 -1.5, 1.5, 1, 0.25。

我尝试过一些方法,比如确定图形中坐标轴的位置,然后把它转换成数据坐标,但没有成功。

非常感谢任何想法或者指引我去看已经回答过的类似问题!

这是我做的(虽然不太好看,但有帮助)。谢谢 tcaswell

#[lower left x, lower left y, upper right x, upper right y] of the desired colorbar:
dat_coord = [-1.5,1.5,-0.5,1.75]
#transform the two points from data coordinates to display coordinates:
tr1 = ax.transData.transform([(dat_coord[0],dat_coord[1]),(dat_coord[2],dat_coord[3])])
#create an inverse transversion from display to figure coordinates:
inv = fig.transFigure.inverted()
tr2 = inv.transform(tr1)
#left, bottom, width, height are obtained like this:
datco = [tr2[0,0], tr2[0,1], tr2[1,0]-tr2[0,0],tr2[1,1]-tr2[0,1]]
#and finally the new colorabar axes at the right position!
cbar_ax = fig.add_axes(datco)
#the rest stays the same:
clevs = [0, 1 , 2]
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs)

plt.show()

2 个回答

1

在数据坐标中指定坐标轴位置的两个步骤:

  1. 使用 Axes.set_axes_locator() 方法来设置一个函数,这个函数会返回一个 Bbox 对象,表示图形坐标中的位置。
  2. 通过 set_clip_box() 方法来设置坐标轴中所有子元素的剪切框。

下面是完整的代码:

import numpy as np
import matplotlib.pyplot as plt    

#Generate some random data:
a = -2
b = 2
x = (b - a) * np.random.random(50) + a
y = (b - a) * np.random.random(50) + a
z = (b) * np.random.random(50)

#Do a scatter plot
fig = plt.figure()
hdl = plt.scatter(x,y,s=20,c=z,marker='o',vmin=0,vmax=2)
ax = plt.gca()
ax.set_xlim([-2,2])
ax.set_ylim([-2,2])

#Specifying figure coordinates works fine:
fig_coord = [0.2,0.8,0.25,0.05]
cbar_ax = fig.add_axes(fig_coord)

def get_ax_loc(cbar_ax, render):
    from matplotlib.transforms import Bbox
    tr = ax.transData + fig.transFigure.inverted()
    bbox = Bbox(tr.transform([[1, -0.5], [1.8, 0]]))
    return bbox

clevs = [0, 1 , 2]
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs)

def get_ax_loc(cbar_ax, render):
    from matplotlib.transforms import Bbox
    tr = ax.transData + fig.transFigure.inverted()
    bbox = Bbox(tr.transform([[1, -0.5], [1.8, 0]]))
    return bbox

def set_children_clip_box(artist, box):
    for c in artist.get_children():
        c.set_clip_box(box)
        set_children_clip_box(c, box)

cbar_ax.set_axes_locator(get_ax_loc)
set_children_clip_box(cbar_ax, hdl.get_clip_box())

plt.show()

这是输出结果:

在这里输入图片描述

2

根据我最初问题的评论,这里是我所做的:

import numpy as np
import matplotlib.pyplot as plt    

a = -2
b = 2

x = (b - a) * np.random.random(50) + a
y = (b - a) * np.random.random(50) + a
z = (b) * np.random.random(50)

fig = plt.figure()
hdl = plt.scatter(x,y,s=20,c=z,marker='o',vmin=0,vmax=2)
ax = plt.gca()
ax.set_xlim([-2,2])
ax.set_ylim([-2,2])

#[(lower left x, lower left y), (upper right x, upper right y)] of the desired colorbar:
dat_coord = [(-1.5,1.5),(-0.5,1.75)]
#transform the two points from data coordinates to display coordinates:
tr1 = ax.transData.transform(dat_coord)
#create an inverse transversion from display to figure coordinates:
inv = fig.transFigure.inverted()
tr2 = inv.transform(tr1)
#left, bottom, width, height are obtained like this:
datco = [tr2[0,0], tr2[0,1], tr2[1,0]-tr2[0,0],tr2[1,1]-tr2[0,1]]
#and finally the new colorabar axes at the right position!
cbar_ax = fig.add_axes(datco)
#the rest stays the same:
clevs = [0, 1 , 2]
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs)

plt.show()

撰写回答