Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib Colorbar change ticks labels and locators

I would like to change the ticks locators and labels in the colorbar of the following plot.

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import dates as mdates
import numpy as np

# fontdict to control style of text and labels
font = {'family': 'serif',
        'color':  (0.33, 0.33, 0.33),
        'weight': 'normal',
        'size': 18,
        }

num = 1000
x = np.linspace(-4,4,num) + (0.5 - np.random.rand(num))
y = np.linspace(-2,2,num) + (0.5 - np.random.rand(num))
t = pd.date_range('1/1/2014', periods=num)

# make plot with vertical (default) colorbar
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(6, 6))
ax.set_title('Scatter plot', fontdict=font)

# plot data
s = ax.scatter(x = x, y = y, 
               s=50, c=t, marker='o', 
               cmap=plt.cm.rainbow)

# plot settings
ax.grid(True)
ax.set_aspect('equal')
ax.set_ylabel('Northing [cm]', fontdict=font)
ax.set_xlabel('Easting [cm]', fontdict=font)

# add colorbar
cbar = fig.colorbar(mappable=s, ax=ax)
cbar.set_label('Date')

# change colobar ticks labels and locators
????

The colorbar illustrates the time dependency. Thus, I would like to change the ticks from their numerical values (nanoseconds?) to more sensible date format like months and year (e.g., %b%Y or %Y-%m) where the interval could be for example 3 or 6 months. Is that possible?

I tried to play unsuccessfully with cbar.formatter, cbar.locator and mdates.

like image 525
AjanO Avatar asked Mar 12 '17 16:03

AjanO


People also ask

How do you rotate a Colorbar label in Python?

Steps to rotate colorbar ticklabels :Plot a figure. Plot corresponding colorbar. Provide ticks and ticklabels. Set rotation of ticklabels to desired angle.

How do I resize a Colorbar in MatPlotLib?

Use fraction parameter to match graph Fraction parameter in colorbar() is used to set the size of colorbar in Python. Using this we can match colorbar size to graph as: If vertical colorbar is used, then fraction=0.047 * (height_of_image / width_of_image)

What is use of the Colorbar in MatPlotLib?

The colorbar() function in pyplot module of matplotlib adds a colorbar to a plot indicating the color scale. Parameters: ax: This parameter is an optional parameter and it contains Axes or list of Axes. values.


2 Answers

You can keep the same locators as proposed by the colorbar function but change the ticklabels in order to print the formatted date as follows:

# change colobar ticks labels and locators 
cbar.set_ticks([s.colorbar.vmin + t*(s.colorbar.vmax-s.colorbar.vmin) for t in cbar.ax.get_yticks()])
cbar.set_ticklabels([mdates.datetime.datetime.fromtimestamp((s.colorbar.vmin + t*(s.colorbar.vmax-s.colorbar.vmin))/1000000000).strftime('%c') for t in cbar.ax.get_yticks()])
plt.show()

which gives the result below:formatted dates as colorbar ticks

If you really want to control tick locations, you can compute the desired values (here for approximately 3 months intervals ~91.25 days):

i,ticks = 0,[s.colorbar.vmin]
while ticks[-1] < s.colorbar.vmax:
   ticks.append(s.colorbar.vmin+i*24*3600*91.25*1e9)
   i = i+1
ticks[-1] = s.colorbar.vmax
cbar.set_ticks(ticks)
cbar.set_ticklabels([mdates.datetime.datetime.fromtimestamp(t/1e9).strftime('%c') for t in ticks])
like image 193
aTben0 Avatar answered Sep 20 '22 00:09

aTben0


The colormapping machinery of matplotlib has no concepts of "units" like an x or y axis does, so you can do the conversion from date to floats manually before mapping and then set the locator and formatter manually. You can also look into how pandas maps their date object to floats, it may be a bit different than the native matplotlib mapping:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

dates = np.datetime64('2019-11-01') + np.arange(10)*np.timedelta64(1, 'D')
X= np.random.randn(10, 2)

plt.scatter(X[:, 0], X[:, 1], c=mdates.date2num(dates))
cb = plt.colorbar()
loc = mdates.AutoDateLocator()
cb.ax.yaxis.set_major_locator(loc)
cb.ax.yaxis.set_major_formatter(mdates.ConciseDateFormatter(loc))
plt.show()

boo

like image 41
Jody Klymak Avatar answered Sep 20 '22 00:09

Jody Klymak