How to smoothly encode 2-dimensional location by colors

139 views Asked by At

In a few webpages (link1, link2) I have seen people filling 2D planes by colors:

Example 1 Example 2

However, these examples are given without source code. How can I generate plot like this in Python? Specifically, if I have array of x and y values, how can I write a function color = f(x, y), so that scatter(x, y, color) can generate plot like this?

So far I have tried the following method:

import numpy as np
import matplotlib.pyplot as plt

base_x_color = np.array([0.0, 1.0, 0.0])
base_y_color = np.array([1.0, 0.0, 0.0])

x = np.random.rand(100000)
y = np.random.rand(100000)
color = x[:,None] * base_x_color[None,:] + y[:,None] * base_y_color[None,:]

plt.figure()
plt.scatter(x, y, s=5, c=color)
plt.show()

However, the generated image (shown below) always have one black corner. I would like to set all four corners as non-black colors, and smoothly transit between them. enter image description here

2

There are 2 answers

0
Sash Sinha On

You can use numpy.meshgrid to implement bilinear interpolation:

import numpy as np
import matplotlib.pyplot as plt

resolution = 500 

x = np.linspace(0, 1, resolution)
y = np.linspace(0, 1, resolution)
X, Y = np.meshgrid(x, y)

color_1 = np.array([1.0, 0.0, 0.0])  # Red
color_2 = np.array([0.0, 1.0, 0.0])  # Green
color_3 = np.array([0.0, 0.0, 1.0])  # Blue
color_4 = np.array([1.0, 1.0, 0.0])  # Yellow

color = np.zeros((resolution, resolution, 3))
color += (1 - X)[:, :, None] * (1 - Y)[:, :, None] * color_1[None, None, :]
color += X[:, :, None] * (1 - Y)[:, :, None] * color_2[None, None, :]
color += (1 - X)[:, :, None] * Y[:, :, None] * color_3[None, None, :]
color += X[:, :, None] * Y[:, :, None] * color_4[None, None, :]

plt.figure()
plt.imshow(color, origin='lower', extent=[0, 1, 0, 1])
plt.show()

Output:

colors

0
Tấn Nguyên On

Base on your code, it seems the np.random.rand produced values near zero, so yes you can use np.random.uniform to control low and high

import numpy as np
import matplotlib.pyplot as plt

base_x_color = np.array([0, 1.0, 0.0])
base_y_color = np.array([1.0, 0, 0.0])

x = np.random.uniform(low=0.5, high=0.8, size=(100000,))
y = np.random.uniform(low=0.5, high=0.8, size=(100000,))

color = x[:,None] * base_x_color[None,:] + y[:,None] * base_y_color[None,:]

plt.figure()
plt.scatter(x, y, s=5, c=color)
plt.show()

enter image description here