Matplotlib colorbar and WCS projection
Asked Answered
F

3

6

I'm trying to write a function to display astronomical images with a colorbar on the top (automaticly with the same length of the x-axis). I'm having problem because when I try to put the tick on the top it doesn't do anything...it keeps the tick on the bottom of the colorbar (and also the tick on the y-axis of the colobar). I think that could be a problem with the WCS coordinate of the x-axis, because when i try to do it without the projection it work well!

import numpy as np
import matplotlib.pyplot as plt
from astropy import wcs
from matplotlib.colors import PowerNorm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib import cm

#WCS coordinate system
w = wcs.WCS(naxis=2)
w.wcs.crpix = [23.5, 23.5]
w.wcs.cdelt = np.array([-0.0035, 0.0035])
w.wcs.crval = [266.8451, -28.151658]
w.wcs.ctype = ["RA---TAN", "DEC--TAN"]
w.wcs.set_pv([(2, 1, 45.0)])

#generate an array as image test
data = (np.arange(10000).reshape((100,100)))

#display image
fig = plt.figure()
ax = plt.gca(projection=w)
graf = ax.imshow(data, origin='lower', cmap=cm.viridis, norm=PowerNorm(1))

#colorbar
divider = make_axes_locatable(ax)
cax = divider.append_axes("top", size="5%")
cbar = fig.colorbar(graf, cax=cax, orientation='horizontal')
cax.xaxis.set_ticks_position('top')
fig.show()

Thanks!

Future answered 1/11, 2017 at 17:57 Comment(3)
This large block of code is rather useless if we can't run it. Try to edit it so others can (at least to the extent of what's possible with your current code) run it and see either the resulting image or the error where it stops.Grecian
To make that short: Please read minimal reproducible example and edit your question accordingly.Burkett
Sorry! I edited the code, now is verifiable!!Future
O
6

You can fix this issue using matplotlib's axes class.

...
import matplotlib.axes as maxes
cax = divider.append_axes("top", size="5%", axes_class=maxes.Axes)
...
Oilla answered 21/9, 2018 at 16:18 Comment(0)
C
2

You need to use the internal machinery of the WCSAxes to handle the ticks in the WCS projection. It looks like WCSAxes handles the colorbar ticks through a coordinate map container (you can find it in cbar.ax.coords) instead of the xaxis/yaxis attributes (that don't seem to be used much).

So, after running your code, the following trick worked for me and the xticks moved up:

c_x = cbar.ax.coords['x']
c_x.set_ticklabel_position('t')
cbar.update_normal(cax)
Coccidioidomycosis answered 2/11, 2017 at 12:8 Comment(2)
It works thanks! but now I see that the range (and the scale) of the colorbar is wrong. It has to be between 0 and 1000 and if I change the norm it has to change the scale...but it doesn't change!Future
Well, the correct ticklabels seem to be stored in cax.xaxis, maybe you can just copy those over to the WCSAxes colorbar somehow?Coccidioidomycosis
J
0

To get something like this to work, I needed a few additional parameters:

            from mpl_toolkits.axes_grid1 import make_axes_locatable
            divider = make_axes_locatable(ax)
            cax = divider.append_axes("right", size="5%", pad=0.05)
            cax.coords[0].grid(False)
            cax.coords[1].grid(False)
            cax.tick_params(direction='in')
            cax.coords[0].set_ticks(alpha=0, color='w', size=0, values=[]*u.dimensionless_unscaled)
            cax.coords[1].set_ticklabel_position('r')
            cax.coords[1].set_axislabel_position('r')

because the default axis gad the grid on, the labels to the left, and x-axis labels enabled. I'm not sure why the original post didn't have issues with this.

Jerome answered 26/4, 2019 at 22:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.