How to set 0 as the color center when using PatchCollection in python?
Question:
I am going to use a circle heatmap to show my results. Here are my code refered from
Heatmap with circles indicating size of population:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
N = 10
M = 11
ylabels = ["".join(np.random.choice(list("PQRSTUVXYZ"), size=7)) for _ in range(N)]
xlabels = ["".join(np.random.choice(list("ABCDE"), size=3)) for _ in range(M)]
x, y = np.meshgrid(np.arange(M), np.arange(N))
s = np.random.randint(0, 180, size=(N,M))
c = np.random.rand(N, M)-0.6
fig, ax = plt.subplots(figsize=(7, 5))
R = s/s.max()/2
circles = [plt.Circle((j,i), radius=r) for r, j, i in zip(R.flat, x.flat, y.flat)]
col = PatchCollection(circles, array=c.flatten(), cmap="RdBu_r")
ax.add_collection(col)
ax.set(xticks=np.arange(M), yticks=np.arange(N),
xticklabels=xlabels, yticklabels=ylabels)
ax.set_xticks(np.arange(M+1)-0.5, minor=True)
ax.set_yticks(np.arange(N+1)-0.5, minor=True)
ax.grid(which='minor')
fig.colorbar(col)
plt.show()
However, I found the center of the colorbar is not zero, i.e.,
I expect the zero of the colorbar is white, but I cannot find parameter like center=0
. How can I achieve this?
Answers:
Because your data is not symmetric around 0.0
(i.e. print(min(c.flatten()), max(c.flatten()))
):
-0.5944467566564706 0.3879256778211414
However, we can manually set the colorbar
‘s min and max values and norm
alize (e.g. -0.6
to 0.6
):
import matplotlib as mpl
...
col = PatchCollection(circles, array=c.flatten(), cmap="RdBu_r", norm=mpl.colors.Normalize(vmin=-0.6, vmax=0.6))
Outputs:
Note: by doing so, none of the values plotted will have dark red colors (since we’ve set the max value for the colorbar
above what is in your dataset).
I am going to use a circle heatmap to show my results. Here are my code refered from
Heatmap with circles indicating size of population:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
N = 10
M = 11
ylabels = ["".join(np.random.choice(list("PQRSTUVXYZ"), size=7)) for _ in range(N)]
xlabels = ["".join(np.random.choice(list("ABCDE"), size=3)) for _ in range(M)]
x, y = np.meshgrid(np.arange(M), np.arange(N))
s = np.random.randint(0, 180, size=(N,M))
c = np.random.rand(N, M)-0.6
fig, ax = plt.subplots(figsize=(7, 5))
R = s/s.max()/2
circles = [plt.Circle((j,i), radius=r) for r, j, i in zip(R.flat, x.flat, y.flat)]
col = PatchCollection(circles, array=c.flatten(), cmap="RdBu_r")
ax.add_collection(col)
ax.set(xticks=np.arange(M), yticks=np.arange(N),
xticklabels=xlabels, yticklabels=ylabels)
ax.set_xticks(np.arange(M+1)-0.5, minor=True)
ax.set_yticks(np.arange(N+1)-0.5, minor=True)
ax.grid(which='minor')
fig.colorbar(col)
plt.show()
However, I found the center of the colorbar is not zero, i.e.,
I expect the zero of the colorbar is white, but I cannot find parameter like center=0
. How can I achieve this?
Because your data is not symmetric around 0.0
(i.e. print(min(c.flatten()), max(c.flatten()))
):
-0.5944467566564706 0.3879256778211414
However, we can manually set the colorbar
‘s min and max values and norm
alize (e.g. -0.6
to 0.6
):
import matplotlib as mpl
...
col = PatchCollection(circles, array=c.flatten(), cmap="RdBu_r", norm=mpl.colors.Normalize(vmin=-0.6, vmax=0.6))
Outputs:
Note: by doing so, none of the values plotted will have dark red colors (since we’ve set the max value for the colorbar
above what is in your dataset).