matplotlibcolorsmarker

Multiple color fills in matplotlib markers


I want to use multiple colors in a marker made with matplotlib. Doing two colors was not that difficult, following this example, and with some additional info from this documentation. However, I was wondering if it is possible to make a marker with more than 2 colors. I'm in a situation where I want a single marker to actually get 3 different colors (a point on a map refers to three different observations).


Solution

  • You can do this by following the matplotlib example shown here:

    https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_piecharts.html

    Below I have changed the example slightly to use ax.plot instead of ax.scatter.

    Basically this means all your marker must have the same size, and instead of using the s kwarg for scatter, you use the ms (or markersize) kwarg for plot.

    Also, instead of facecolor you need to define markerfacecolor.

    Other than those changes, everything else remains the same as the original example.

    """
    This example makes custom 'pie charts' as the markers for a scatter plot
        
    Thanks to Manuel Metz for the example
    """
    import numpy as np
    import matplotlib.pyplot as plt
    
    # first define the ratios
    r1 = 0.2       # 20%
    r2 = r1 + 0.4  # 40%
    
    # define some sizes of the scatter marker
    sizes = np.array([60, 80, 120])
    
    # calculate the points of the first pie marker
    #
    # these are just the origin (0,0) +
    # some points on a circle cos,sin
    x1 = np.cos(2 * np.pi * np.linspace(0, r1))
    y1 = np.sin(2 * np.pi * np.linspace(0, r1))
    xy1 = np.row_stack([[0, 0], np.column_stack([x1, y1])])
    s1 = np.abs(xy1).max()
    
    x2 = np.cos(2 * np.pi * np.linspace(r1, r2))
    y2 = np.sin(2 * np.pi * np.linspace(r1, r2))
    xy2 = np.row_stack([[0, 0], np.column_stack([x2, y2])])
    s2 = np.abs(xy2).max()
    
    x3 = np.cos(2 * np.pi * np.linspace(r2, 1))
    y3 = np.sin(2 * np.pi * np.linspace(r2, 1))
    xy3 = np.row_stack([[0, 0], np.column_stack([x3, y3])])
    s3 = np.abs(xy3).max()
    
    fig, ax = plt.subplots()
    
    # Here's where I made changes
    ax.plot(np.arange(3), np.arange(3), marker=xy1,
               ms=20, markerfacecolor='blue', markeredgecolor='None', linestyle='None')   # I changed this line
    ax.plot(np.arange(3), np.arange(3), marker=xy2,
               ms=20, markerfacecolor='green', markeredgecolor='None', linestyle='None')  # I changed this line
    ax.plot(np.arange(3), np.arange(3), marker=xy3,
               ms=20, markerfacecolor='red', markeredgecolor='None', linestyle='None')    # I changed this line
    
    
    plt.margins(0.05)
        
    plt.show()
    

    enter image description here