Home > database >  Color code of lines based on an array using Matplotlib
Color code of lines based on an array using Matplotlib

Time:07-14

I am drawing multiple horizontal and vertical lines using ax.hlines() and ax.vlines() respectively. I want to assign values to these lines using the array P and the order of assignment is presented in the expected output.

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np

fig,ax = plt.subplots(1)
n=3
for i in range(0,n):
    for j in range(0,n):
        rect = mpl.patches.Rectangle((200 200*i,200 200*j),10*n, 10*n, linewidth=1, edgecolor='black', facecolor='black')
        ax.add_patch(rect)
        ax.hlines(200 200*i 5*n, 200, 200*n, zorder=0)
        ax.vlines(200 200*j 5*n, 200, 200*n, zorder=0)

ax.set_xlim(left = 0, right = 220*n)
ax.set_ylim(bottom = 0, top = 220*n)
plt.show()

#########################################
P=np.array([[1.9],
       [4.9],
       [6.1],
       [8.2],
       [1.8],
       [5.8],
       [9.7],
       [7.3],
       [8.9],
       [2.5],
       [9.9],
       [0.7]])

#########################################

The current output is

enter image description here

The expected output is

enter image description here

CodePudding user response:

You need to use a colormap, Normalize and ScalarMappable in order to create a colorbar.

Here is the procedure:

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

#########################################
P=np.array([[1.9],
       [4.9],
       [6.1],
       [8.2],
       [1.8],
       [5.8],
       [9.7],
       [7.3],
       [8.9],
       [2.5],
       [9.9],
       [0.7]])

#########################################

# normalize the values. Values between 0 and 10 will be
# normalized to values from 0 and 1.
norm = Normalize(vmin=0, vmax=10)
Pnorm = norm(P)
# choose an appropriate colormap
cmap = cm.Blues

fig,ax = plt.subplots(1)
n=3
k = 0
for i in range(0,n):
    for j in range(0,n):
        rect = mpl.patches.Rectangle((200 200*i,200 200*j),10*n, 10*n, linewidth=1, edgecolor='black', facecolor='black')
        ax.add_patch(rect)
        # extract the color from the colormap
        ax.hlines(200 200*i 5*n, 200, 200*n, zorder=0, color=cmap(Pnorm[k]))
        ax.vlines(200 200*j 5*n, 200, 200*n, zorder=0, color=cmap(Pnorm[k]))
        k  = 1

cb = fig.colorbar(ScalarMappable(cmap=cmap, norm=norm))
cb.set_label("Values")
ax.set_xlim(left = 0, right = 220*n)
ax.set_ylim(bottom = 0, top = 220*n)
plt.show()

There is a problem with the way you are currently plotting lines, as they are overlapping. You need to fix it!

CodePudding user response:

Values bar is added following @Davide_sd.

I'm not sure if this sovles your problem.

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


fig,ax = plt.subplots(1)
n=3

P=np.array([[1.9],
       [4.9],
       [6.1],
       [8.2],
       [1.8],
       [5.8],
       [9.7],
       [7.3],
       [8.9],
       [2.5],
       [9.9],
       [0.7]])

color = cm.get_cmap('Blues')
norm = Normalize(vmin=0, vmax=10)
color_list = []
for i in range(len(P)):
    color_list.append(color(P[i]/10))
print(color_list)
id = 0
for j in range(0, n):
    # id = 4 * j
    ax.hlines(200 200*(n-j-1) 5*n, 200 5*n, 200*(n-1) 5*n, zorder=0, colors=color_list[id])
    id  = 1
    ax.hlines(200 200*(n-j-1) 5*n, 200*(n-1) 5*n, 200*n 5*n, zorder=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, edgecolor='black', facecolor='black')
        ax.add_patch(rect)
        if j==2:
            break
        ax.vlines(200 200*i 5*n, 200*(n-1-j) 5*n, 200*(n-j) 5*n, zorder=0, colors=color_list[id])
        id  = 1

cb = fig.colorbar(cm.ScalarMappable(cmap=color, norm=norm))
cb.set_label("Values")
ax.set_xlim(left = 0, right = 220*n)
ax.set_ylim(bottom = 0, top = 220*n)
plt.show()

And the ouput is like:enter image description here

  • Related