Legends and annotations explain data plots clearly and in context. By assigning each plot a short description about what data it represents, we are enabling an easier mental model in the reader's (viewer's) head. This recipe will show how to annotate specific points on our figures and how to create and position data legends.
How many times have you looked at a chart and wondered what the data represents? More often than not, newspapers and other daily and weekly publications create plots that don't contain appropriate legends, thus leaving the reader free to interpret the representation. This creates ambiguity for the readers and increases the possibility of error.
Let's demonstrate how to add legends and annotations with the following example:
from matplotlib.pyplot import * # generate different normal distributions x1 =np.random.normal(30, 3, 100) x2 = np.random.normal(20, 2, 100) x3 = np.random.normal(10, 3, 100) # plot them plot(x1, label='plot') plot(x2, label='2nd plot') plot(x3, label='last plot') # generate a legend box legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=3, mode="expand", borderaxespad=0.) # annotate an important value annotate("Important value", (55,20), xycoords='data', xytext=(5, 38), arrowprops=dict(arrowstyle='->')) show()
The preceding code will give us the following plot:
What we do is assign a string label with every plot, so legend()
will try and determine what to add in the legend box.
We set the location of a legend box by defining the loc
parameter. This is optional, but we want to specify a location where it is least likely for the legend box to be drawn over plot lines. Setting the location value to 0
is very useful as it automatically detects the location of the figure where the legend can fit with a minimum overlapping with the plot.
All location parameter strings are given in the following table:
String |
Number value |
---|---|
best |
0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To not show the label in a legend, set the label to _nolegend_
.
For the legend, we defined the number of columns with ncol = 3
and set the location with lower left
. We specified a bounding box (bbox_to_anchor
) to start from position (0., 1.02)
and to have a width of 1
and a height of 0.102
. These are normalized axis coordinates. Parameter mode
is either None
or expand
to allow the legend box to expand horizontally filling the axis area. The parameter borderaxespad
defines the padding between the axes and the legend border.
For annotations, we have defined a string to be drawn on a plot on a coordinate xy
. The coordinate system is specified to be the same as the data one; therefore, coordinate system is xycoord = 'data'
. The starting position for the text is defined by the value of xytext
.
An arrow is drawn from xytext
to xy
coordinate and the arrowprops
dictionary can define many properties for that arrow. For this example, we used arrowstyle
to define arrow style.