Reputation: 1363
Consider the folowing plot:
fig, ax = plt.subplots(figsize = (14, 6))
ax.set_facecolor('k')
ax.set_xlim(0, 100)
ax.set_ylim(0, 100)
xs = np.arange(60, 70) # xs = np.linspace(60, 70, 100)
ys = np.arange(0, 100, .5) # ys = np.linspace(0, 100, 100)
v = [[[x, y] for x in xs] for y in ys]
lines = LineCollection(v, linewidth = 1, cmap = plt.cm.Greys_r)
lines.set_array(xs)
ax.add_collection(lines)
How can I change the color of the lines according to their x
coordinates (horizontally) so as to create a "shading" effect like this:
Here, the greater x
is, the "whiter" the LineCollection
is.
Following this reasoning, I thought that specifying lines.set_array(xs)
would do the trick but as you can see in my plot the color gradation is still following the y axis. Strangely the pattern is repeating itself, from black to white (every 5) over and over (up to 100).
I think (not sure at all) the problem lies in the v
variable that contains the coordinates. The concatenation of x
and y
might be improper.
Upvotes: 2
Views: 2921
Reputation: 339795
The shape of the list v
you supply to the LineCollection
is indeed not suitable to create a gradient of the desired direction. This is because each line in a LineCollection can only have single color. Here the lines range from x=60 to x=70 and each of those lines has one color.
What you need to do instead is to create a line collection where each line is devided into several segments, each of which can then have its own color.
To this end an array of dimensions (n, m, l)
, where n
is the number of segments, m
is the number of points per segment, and l
is the dimension (2D, hence l=2
) needs to be used.
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import LineCollection
fig, ax = plt.subplots(figsize = (14, 6))
ax.set_facecolor('k')
ax.set_xlim(0, 100)
ax.set_ylim(0, 100)
xs = np.linspace(60, 70, 100)
ys = np.linspace(0, 100, 100)
X,Y = np.meshgrid(xs,ys)
s = X.shape
segs = np.empty(((s[0])*(s[1]-1),2,2))
segs[:,0,0] = X[:,:-1].flatten()
segs[:,1,0] = X[:,1:].flatten()
segs[:,0,1] = Y[:,:-1].flatten()
segs[:,1,1] = Y[:,1:].flatten()
lines = LineCollection(segs, linewidth = 1, cmap = plt.cm.Greys_r)
lines.set_array(X[:,:-1].flatten())
ax.add_collection(lines)
plt.show()
Upvotes: 3