Matplotlib sets up a legend to display squares instead of rectangles

Here is my attempt to change the barplot legend from rectangle to square:

import matplotlib.patches as patches

rect1 = patches.Rectangle((0,0),1,1,facecolor='#FF605E')
rect2 = patches.Rectangle((0,0),1,1,facecolor='#64B2DF')
plt.legend((rect1, rect2), ('2016', '2015'))

But when I draw this, I still see rectangles instead of squares:

enter image description here

Any suggestions on how I can do this?


I tried both solutions provided by @ImportanceOfBeingErnest and @furas, here are the results:

The @ImportanceOfBeingErnest solution is the easiest:

plt.rcParams['legend.handlelength'] = 1
plt.rcParams['legend.handleheight'] = 1.125

Here is the result:

enter image description here

My last code is as follows:

plt.legend((df.columns[1], df.columns[0]), handlelength=1, handleheight=1) # the df.columns = the legend text

The @furas solution produces this, I donโ€™t know why the texts are further from the rectangles, but I am sure that the gap can be somehow changed:

enter image description here

+4
source share
2 answers

Matplotlib provides rcParams

legend.handlelength  : 2.    # the length of the legend lines in fraction of fontsize
legend.handleheight  : 0.7   # the height of the legend handle in fraction of fontsize

, , plt.legend()

plt.legend(handlelength=1, handleheight=1)

rcParams script

import matplotlib
matplotlib.rcParams['legend.handlelength'] = 1
matplotlib.rcParams['legend.handleheight'] = 1

, handlelength=1, handleheight=1 . , handlelength=1, handleheight=1.125 , .


, -, plot/scatter.

bar1 = plt.plot([], marker="s", markersize=15, linestyle="", label="2015")

legend(handles=[bar1]). matplotlib.rcParams['legend.numpoints'] = 1, .


.
import matplotlib.pyplot as plt
plt.rcParams['legend.handlelength'] = 1
plt.rcParams['legend.handleheight'] = 1.125
plt.rcParams['legend.numpoints'] = 1


fig, ax = plt.subplots(ncols=2, figsize=(5,2.5))

# Method 1: Set the handlesizes already in the rcParams
ax[0].set_title("Setting handlesize")
ax[0].bar([0,2], [6,3], width=0.7, color="#a30e73", label="2015", align="center")
ax[0].bar([1,3], [3,2], width=0.7, color="#0943a8", label="2016", align="center" )
ax[0].legend()

# Method 2: use proxy markers. (Needs legend.numpoints to be 1)
ax[1].set_title("Proxy markers")
ax[1].bar([0,2], [6,3], width=0.7, color="#a30e73", align="center" )
ax[1].bar([1,3], [3,2], width=0.7, color="#0943a8", align="center" )
b1, =ax[1].plot([], marker="s", markersize=15, linestyle="", color="#a30e73",  label="2015")
b2, =ax[1].plot([], marker="s", markersize=15, linestyle="", color="#0943a8",  label="2016")
ax[1].legend(handles=[b1, b2])

[a.set_xticks([0,1,2,3]) for a in ax]
plt.show()

enter image description here

+2

, - - .

handler:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.legend_handler import HandlerPatch

# --- handlers ---

class HandlerRect(HandlerPatch):

    def create_artists(self, legend, orig_handle,
                       xdescent, ydescent, width, height,
                       fontsize, trans):

        x = width//2
        y = 0
        w = h = 10

        # create
        p = patches.Rectangle(xy=(x, y), width=w, height=h)

        # update with data from oryginal object
        self.update_prop(p, orig_handle, legend)

        # move xy to legend
        p.set_transform(trans)

        return [p]


class HandlerCircle(HandlerPatch):

    def create_artists(self, legend, orig_handle,
                       xdescent, ydescent, width, height,
                       fontsize, trans):

        r = 5
        x = r + width//2
        y = height//2

        # create 
        p = patches.Circle(xy=(x, y), radius=r)

        # update with data from oryginal object
        self.update_prop(p, orig_handle, legend)

        # move xy to legend
        p.set_transform(trans)

        return [p]

# --- main ---

rect = patches.Rectangle((0,0), 1, 1, facecolor='#FF605E')
circ = patches.Circle((0,0), 1, facecolor='#64B2DF')

plt.legend((rect, circ), ('2016', '2015'),
            handler_map={
               patches.Rectangle: HandlerRect(),
               patches.Circle: HandlerCircle(),
            })

plt.show()

, , .

enter image description here

+2

Source: https://habr.com/ru/post/1661156/


All Articles