58

I'm trying to make a plot in matplotlib with transparent markers which have a fixed color edge . However, I can't seem to achieve a marker with transparent fill.

I have a minimum working example here:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y1 = 2*x + 1
y2 = 3*x - 5

plt.plot(x,y1, 'o-', lw=6, ms=14)
plt.plot(x,y2, 'o', ms=14, markerfacecolor=None, alpha=0.5, markeredgecolor='red', markeredgewidth=5)

plt.show()

I tried two techniques I found online to achieve this: 1) Setting alpha parameter. However, this makes the marker edge transparent too, which is not the desired effect. 2) Setting markerfacecolor=None, although this has no effect on my plot

Is there a solution to this please?

Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234
IanRoberts
  • 2,846
  • 5
  • 26
  • 33

2 Answers2

91

This is tricky in Matplotlib... you have to use a string "None" instead of the value None, then you can just do:

plt.plot(x,y2, 'o', ms=14, markerfacecolor="None",
         markeredgecolor='red', markeredgewidth=5)
Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234
  • 46
    As a side note, there is a very good reason for the difference between `None` and `'None'`. The first means 'do the default thing', the later means "I don't want a color". – tacaswell May 12 '14 at 13:34
  • 1
    I was just wondering why the simple `None` was not doing what I wanted (empty marker). It is a bit confusing though. – Gabriel Mar 06 '18 at 14:24
  • 3
    @Gabriel this is common. In Matplotlib `None` means default while `"None"` means that no color should be used – Saullo G. P. Castro Mar 06 '18 at 17:24
  • I don't see how this answers the question: The result does not have "a marker with transparent fill" (i.e. with an alpha), it is not filled at all. Adding a second plot for the transparent markers is not a solution either, because the color cycle can no longer be used (easily). – bluenote10 Jun 08 '18 at 13:37
  • @bluenote the OP wanted to keep the edges solid while the fill transparent... This was the way I could figure out how to get it done. If you need not full transparency then the second plot would do the trick with the drawbacks you mentioned – Saullo G. P. Castro Jun 08 '18 at 19:28
  • 4
    it appears that also specifying the 'alpha' breaks this solution...by providing it, I was getting black fill. removing it, I got no fill – eqzx Jun 29 '18 at 22:39
  • 2
    The alpha breaking does not appear to be a problem in the current matplotlib version (3.0.2, here). Adding `alpha = 0.5` to this solution behaves as expected – SpinUp __ A Davis Mar 08 '19 at 17:59
  • When using certain other plotting functions like `ax.voxels` I'm getting the black fill bug on matplotlib version 3.0.3 – Robin De Schepper Sep 20 '19 at 15:54
8

In general it seems to be a better solution to use transparent colors, instead of the alpha parameter. First of all because it does not affect any other colors and it helps to avoid the black fill bug reported by some in the comments. In this example - using the voxels function to draw 2 voxels on the plot - the 4th number in the tuples stored in colors represents the alpha value of an RGBA color. These normalized RGBA tuple notations can be used as colors throughout matplotlib.

import matplotlib.pyplot as plt, numpy as np, mpl_toolkits.mplot3d
fig = plt.figure()
ax = fig.gca(projection='3d')
voxels = np.array([[[True],[True]]])
colors = np.array([[[(0., 0., 0., 0.)],[(1.0, 0., 0., 0.5)]]])
ax.voxels(voxels, facecolors=colors, edgecolor='k', linewidth=.5)
plt.show(block=True)

enter image description here

Robin De Schepper
  • 4,942
  • 4
  • 35
  • 56