I would like to position a colorbar inside a scatter plot by specifying the position in data coordinates. Here is an example of how it works when specifying figure coordinates:
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()
...Ok, can't include an image of the plot here because I am lacking reputation. But the above code will give you an impression....
Now the question is, how could I position the colorbar at data coordinates, to appear at e.g.: left, bottom, width, height: -1.5, 1.5, 1, 0.25
I have experimented with a few things, like determining the axes position within the figure and transforming it to data coordinates but didn't succeed.
Many thanks for ideas or pointing me to already answered similar questions!
Here is what I did (not particularly beautiful but it helps). Thanks 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()
The position of the Matplotlib color bar can be changed according to our choice by using the functions from Matplotlib AxesGrid Toolkit. The placing of inset axes is similar to that of legend, the position is modified by providing location options concerning the parent box. Axes into which the colorbar will be drawn.
To specify the value of axes, create a list of characters. Use xticks and yticks method to specify the ticks on the axes with x and y ticks data points respectively. Plot the line using x and y, color=red, using plot() method.
Here is what I did, based on the comments to my original question:
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()
Two step to specify the position in data coordinates of an Axes:
Axes.set_axes_locator()
to set a function that return a Bbox
object in figure coordinate.set_clip_box()
method:Here is the full code:
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()
And here is the output:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With