Reputation: 131
I want to have a scatter plot with colormap for edgecolors but no facecolors.
When I use facecolor='None'
, it does not work.
import numpy as np
import matplotlib.pyplot as plt
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radii
plt.scatter(x, y, s=area,c=colors,facecolors='None',cmap="gist_rainbow", alpha=0.5)
plt.show()
Any solution?
Upvotes: 11
Views: 19969
Reputation: 1
I wanted to answer to nasgold as I have found and answer for the colorbar. I have mixed answers from different topics to create the edgecolor and retrieve it for the colorbar.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcb
import matplotlib.cm as cm
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
z = np.sqrt(x*y)
#we choose a colorblind palette
cmap = cm.plasma
#here we define the colors of edgecolors for the scatter plot with the min and max
norm = mcb.Normalize(z.min(),z.max())
edgecols = cmap(norm(z))
#we get the color from the edgecolors values
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array(edgecols)
plt.scatter(x,y,edgecolors=edgecols,
c='none',marker='o',lw=1,s=10)
#we plot the colorbar with the colors from edgecolor
cbar = plt.colorbar(sm)
Upvotes: 0
Reputation: 11
I know this has been dead for a while, but I wanted to add my experience as I just encountered this same problem.
I prefer Diziet's method as passing the PathCollection object to a colorbar and having it match the cmap used in the scatter plot works exactly as it would if you didn't alter the facecolors.
With the accepted solution, however, I encountered some odd behavior where even after removing the cmap argument from the ax.scatter call the scatter plot edge colormap and the colorbar colormap didn't match.
Upvotes: 0
Reputation: 40737
The problem is that color=
overrides the facecolors=
argument.
The solution I came up with is to get the PathCollection
returned by pyplot.scatter()
and then change the facecolor
directly. Note that you probably need to increase the line width to see the edges better.
import numpy as np
import matplotlib.pyplot as plt
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radii
a = plt.scatter(x, y, s=area,c=colors,facecolor='none',lw=2,cmap="gist_rainbow", alpha=0.5)
a.set_facecolor('none')
plt.show()
Upvotes: 7
Reputation: 339560
The c
argument will affect facecolor and edgecolor simultaneouly, the arguments facecolor
and edgecolor
are hence ignored.
A solution would be not to use the c
argument together with a colormap, but instead use facecolors
and edgecolors
alone. In this case facecolors
can be set to "None"
and edgecolors
can be given a list of colors to use.
To create this list, the same colormap can be applied.
c = plt.cm.gist_rainbow(colors)
plt.scatter(x, y, s=area,facecolors="None", edgecolors=c, lw=1,alpha=0.5)
A complete example:
import numpy as np
import matplotlib.pyplot as plt
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radii
c = plt.cm.gist_rainbow(colors)
plt.scatter(x, y, s=area,facecolors="None", edgecolors=c, lw=2,alpha=0.5)
plt.show()
Upvotes: 12