I have to do a scatter plot that has colors depending on a third variable. If the variable is between 0 and 1, give "blue", 1-2, red, 2-3, purple, 3-4, green, 4-5 gray. How can I do that ?
x = [1,2,3,4,5] y = [3,4,2,3,4] c = [1,2,4,0.5,5] I have to do a scatter plot that has colors depending on a third variable. If the variable is between 0 and 1, give "blue", 1-2, red, 2-3, purple, 3-4, green, 4-5 gray. How can I do that ?
x = [1,2,3,4,5] y = [3,4,2,3,4] c = [1,2,4,0.5,5] If you want specific boundaries for the colormap you can use mpl.colors.BoundaryNorm together with mpl.colors.ListedColormap.
import matplotlib.pyplot as plt import matplotlib as mpl x = [1,2,3,4,5] y = [3,4,2,3,4] c = [1,2,4,0.5,5] cmap = mpl.colors.ListedColormap(['blue','red','magenta', 'green', 'gray']) c_norm = mpl.colors.BoundaryNorm(boundaries=[0,1,2,3,4,5], ncolors=5) plt.scatter(x, y, c=c, s=200, cmap=cmap, norm=c_norm) plt.colorbar() plt.show() Which gives this plot:
You can create and use a listed colormap:
import matplotlib as mpl import matplotlib.pyplot as plt x = [1,2,3,4,5] y = [3,4,2,3,4] c = [1,2,4,0.5,5] cmap = mpl.colors.ListedColormap( [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) plt.scatter(x, y, c=c, s=100, cmap=cmap) plt.show() c list different than this example, you will get wrong colors.Here is another example, coloring a scatter plot depending on age.
The BoundaryNorm set the boundaries for each age range and associate a color to each.
If, for example there are age ranges < 18, 18-40, 40-65, 65-80, > 80, you could list these boundaries as [18,40,65,80]. The BoundaryNorm needs one more bound than the number of colors, so you could add 0 at the front and 100 at the end.
You can create a colormap from an existing colormap, giving the number of colors needed: plt.cm.get_cmap('plasma_r', len(boundaries)+1) or as a ListedColormap, giving it an explicit list of colors: matplotlib.colors.ListedColormap([...]).
Example code:
import matplotlib from matplotlib import pyplot as plt import pandas as pd import numpy as np N = 30 df = pd.DataFrame({'x': np.random.randint(4,12,N), 'y': np.random.randint(4,10,N), 'birthdt': np.random.randint(1,95, N)}) boundaries = [18, 40, 65, 80] cmap = matplotlib.colors.ListedColormap(['limegreen', 'dodgerblue', 'crimson', 'orange', 'fuchsia']) # cmap = plt.cm.get_cmap('plasma_r', len(boundaries) + 1) norm = matplotlib.colors.BoundaryNorm([0]+boundaries+[100], len(boundaries)+1) plt.scatter(df.x, df.y, s=60, c=df.birthdt, cmap=cmap, norm=norm) cbar = plt.colorbar(extend='max') cbar.ax.set_ylabel('Age') plt.show() If you'd like the colorbar separations in proportion to the age ranges, you can try:
import matplotlib from matplotlib import pyplot as plt import pandas as pd import numpy as np N = 30 df = pd.DataFrame({'x': np.random.randint(4, 12, N), 'y': np.random.randint(4, 10, N), 'birthdt': np.random.randint(1, 95, N)}) boundaries = [18, 30, 65, 80] max_age = 100 base_colors = ['limegreen', 'dodgerblue', 'crimson', 'orange', 'fuchsia'] full_colors = [c for c, b0, b1 in zip(base_colors, [0] + boundaries, boundaries + [max_age]) for i in range(b1 - b0)] cmap_full = matplotlib.colors.ListedColormap(full_colors) norm_full = matplotlib.colors.Normalize(vmin=0, vmax=max_age) plt.scatter(df.x, df.y, s=60, c=df.birthdt, cmap=cmap_full, norm=norm_full) cbar = plt.colorbar(extend='max', ticks=boundaries) cbar.ax.set_ylabel('Age') plt.show()