Mismatch in ticks of colorbar using Matplotlib

Question:

I am plotting an array, Pe of shape (220,220). There is mismatch in some ticks of the colorbar as highlighted using the red circle. Basically, I want each color on the colorbar to have one well defined end value. How do I accomplish this?

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np
from matplotlib.colors import Normalize
from matplotlib import cm
import math
from  numpy import nan

fig,aPe = plt.subplots(1)
n=11
arMax=[]
arMin=[]

N=2*n*(n-1)

J = np.array([[]])

Pe=np.array([[397.9245283 , 431.37280501, 423.07492578, 448.72320111,
       415.76282885, 403.98056072, 406.32617702, 439.50026536,
       398.74902582, 402.08146852, 416.21242203, 427.5394595 ,
       427.06507633, 413.08553581, 412.20075077, 437.50197698,
       437.75076871, 398.33635041, 401.03411236, 436.50963158,
       414.19687294, 439.2494816 , 413.7516213 , 401.87155987,
       430.88988181, 422.61039289, 420.07358693, 411.75977806,
       448.46178462, 403.76866504, 425.41299332, 436.26224822,
       402.92330055, 399.36964466, 437.00524093, 430.16752099,
       414.86655013, 426.59174471, 401.66187026, 418.70266927,
       438.74877169, 416.66298861, 409.56899181, 408.04926082,
       399.9921984 , 447.93986435, 429.20813236, 432.34190614,
       426.8282793 , 407.83307657, 417.34067053, 417.11453175,
       429.68729115, 438.49884457, 423.54048103, 421.91550311,
       441.01100224, 402.71251224, 427.77704651, 441.26380205,
       444.06384971, 406.9706254 , 442.78670822, 431.13120817,
       429.92727196, 435.27551245, 444.3201626 , 447.6793595 ,
       404.40501999, 413.30732589, 407.40139454, 404.83037214,
       408.69919091, 445.3483799 , 428.49139455, 434.53838488,
       434.04835195, 427.30213625, 440.75849192, 412.64266901,
       406.11181421, 412.42159151, 430.64882546, 400.20014785,
       433.07159431, 405.68376641, 411.10008524, 437.25346787,
       419.61561798, 428.2530136 , 439.75133565, 440.25433778,
       405.25662001, 433.80374971, 422.14687898, 432.8280914 ,
       442.02394342, 424.70886414, 423.77364309, 403.34553985,
       425.64822218, 424.4746721 , 405.04338393, 404.19267892,
       408.9162946 , 421.45351141, 398.54258129, 443.55211004,
       447.41915748, 410.22377598, 434.29323018, 442.27790619,
       445.60617823, 446.6403631 , 432.09922288, 420.53255663,
       436.01514511, 412.86398365, 440.00269296, 420.30294648,
       436.75729566, 418.47505247, 400.61669609, 425.17802432,
       411.53964533, 444.57677156, 438.24920203, 408.48231763,
       406.75558225, 423.3075754 , 419.38700777, 415.31420594,
       417.56705465, 428.73004103, 418.24768301, 441.77027214,
       443.29668225, 407.61712126, 414.41985832, 417.7936845 ,
       406.54076625, 424.007062  , 403.13430964, 413.9741274 ,
       401.45239937, 432.58486216, 415.09025734, 411.31974785,
       446.12267131, 398.13033286, 415.53839631, 400.40831363,
       444.83367708, 422.84253175, 422.37850877, 426.11946115,
       409.35119469, 445.86427519, 416.43758344, 429.4475781 ,
       428.01489773, 430.40803867, 440.5062706 , 402.29159657,
       446.89965981, 408.26567439, 410.44250286, 415.98750396,
       443.04154848, 416.88863791, 421.68438072, 448.20067254,
       398.95568434, 399.78446494, 399.16255717, 405.47008071,
       433.559423  , 428.96895348, 419.84447757, 411.98014641,
       405.89767746, 409.78702083, 410.66146312, 431.61467276,
       434.78381651, 410.88065712, 414.64308392, 426.35547214,
       442.53216095, 441.51689185, 410.00528209, 418.02056049,
       409.13362907, 419.15864652, 447.15925776, 420.76241778,
       400.82529555, 431.8568119 , 421.22289476, 420.99253035,
       433.31537135, 402.50194436, 446.3813671 , 438.99898387,
       418.93053382, 445.09087969, 407.18589604, 443.80783236,
       435.76832176, 435.52177769, 399.57694714, 425.88371131,
       424.94331474, 404.61758428, 437.99984357, 403.55699154,
       413.52935426, 435.02952554, 424.2407382 , 397.9245283 ]])

C1 = nan
for i in J[0]:
    Pe = np.insert(Pe, i, [C1], axis=1)
print("Pe =", [Pe])

for i in range(0,len(Pe)):
    Max=max(max(Pe[i]), max(Pe[i]))
    Min=min(min(Pe[i]), min(Pe[i]))
    
    arMax.append(Max)
    Max=np.array(arMax)
    
    arMin.append(Min)
    Min=np.array(arMin)

a=min(Min)
b=max(Max)

print("a =",a)
print("b =",b)


Amax= math.ceil(b)
Amin= math.floor(a)
print(Amax, Amin)

color = cm.get_cmap('Dark2')
norm = Normalize(vmin=Amin, vmax=Amax)
color_list = []
for i in range(len(Pe[0])):   
    color_list.append(color(((Pe[0,i])-Amin)/(Amax-Amin)))
    
id = 0
for j in range(0, n):
    for k in range(n-1):
        aPe.hlines(200+200*(n-j-1)+5*n, 200*(k+1)+5*n, 200*(k+2)+5*n, zorder=0, linewidth=5.0,colors=color_list[id])
        id += 1

    for i in range(0, n):
        rect = mpl.patches.Rectangle((200+200*i, 200+200*j), 10*n, 10*n, linewidth=1.0, edgecolor='black', facecolor='black')
        aPe.add_patch(rect)
        if j < n-1:
            aPe.vlines(200+200*i+5*n, 200*(n-1-j)+5*n, 200*(n-j)+5*n, zorder=0,linewidth=5.0, colors=color_list[id])
            id += 1

cb = fig.colorbar(cm.ScalarMappable(cmap=color, norm=norm), ticks=np.arange(Amin, Amax+len(color.colors), len(color.colors)))
cb.set_ticks(np.arange(Amin, Amax+1, (Amax-Amin)/8).astype(np.int64))
cb.set_label("Entry pressure (N/m$^{2}$)")

aPe.set_xlim(left = 0, right = 220*n)
aPe.set_ylim(bottom = 0, top = 220*n)
plt.axis('off')
plt.title("Time = 5",fontsize=20)
plt.show()

enter image description here

Asked By: user19862793

||

Answers:

At present, you are first setting ticks with:

ticsk=np.arange(Amin, Amax+len(color.colors), len(color.colors))
# array([397, 405, 413, 421, 429, 437, 445, 453])

This would have produced a more serious mismatch still (notice that this array has length 8, while you are looking for 9 tick labels, as in the arrays below).

But you overwrite this with:

cb.set_ticks(np.arange(Amin, Amax+1, (Amax-Amin)/8).astype(np.int64))
# array([397, 403, 410, 416, 423, 429, 436, 442, 449], dtype=int64)

As mentioned in the comments by @r-beginners, here you introduce a mismatch by turning floats into integers. The original floats being:

np.arange(Amin, Amax+1, (Amax-Amin)/8)
array([397. , 403.5, 410. , 416.5, 423. , 429.5, 436. , 442.5, 449. ])

What you want to do, is first pass the actual float values to ticks and then simply adjust their formatting. E.g.:

tks = np.arange(Amin, Amax+1, (Amax-Amin)/8)

cb = fig.colorbar(cm.ScalarMappable(cmap=color, norm=norm), ticks=tks)
cb.set_ticklabels(['{:.0f}'.format(t) for t in tks])

# or: cb.set_ticklabels([str(int(t)) for t in tks])

Result:

colorbar

Answered By: ouroboros1
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.