My plots just Sucked. Here is how I fixed them.

Original article was published by Bex Tuychiev on Artificial Intelligence on Medium


Annotating text, deep guide

Regardless of how beautiful and informative your plots are, sometimes it can be very difficult to read them. So, instead of providing a description as a wall of text, you can use annotations together with arrows to point to important parts of the plot. This section is about placing text in any part of the plot.

First, let’s place a text to an empty figure:

We create an empty subplot. Then, I set the axis limits to plot a larger figure. The first argument annotate() accepts is the text to be placed. The next and probably most important parameter is xycoords. It can accept a range of values but the best is to set it to data. This means that we define the coordinates of the text based on our data. So, when I set xy parameter to (3, 3) it places them depending on the axis values. Let’s add another text 1 point above the previous:

We adjusted the y value of xy to put a text 1 point above the previous. Note that since I set xycoords to data, the units are calculated to match the axis ticks. If we have dates on the XAxis, you would provide a date to xy to specify the x coordinate.

Sometimes, the grid joints might not be the best place to put the text. You might want to point to a specific part of the plot but want the text to appear from some other offset. For example, the above example places the text to (3, 3) coordinates. But what if we want to point to that same point but want the text to appear a little above and a little to the left? Matplotlib provides two other parameters for these situations:

textcoords just like xycoords accepts different scaling units. If we set textcoords to offset points, matplotlib interprets the x and y values as to how many units off xy we want to move the text. So interpreting the above code, we want to annotate the (3, 3) point but want the text to appear at 30 points above and 25 points to the left. This method is really flexible because it allows controlling the location of the text in any way we want.

Now, let’s get back to our example. We have a count plot but instead of leaving the audience guessing, we want to place the height of each bar on top of itself. This will greatly help the interpretation. Let’s see the plot:

To put a text above each bar, we have to find out each of their heights. The reason I assigned the plot to a variable is that it provides some additional attributes about the plot:

Any plot with bars have a useful attribute we can use called patches:

As you see, there are 6 Rectangle objects just as there are 6 bars in the plot. We printed the first bar and from the output, it can be seen that its height is 175. Now, let’s loop over each Rectangle object and get their height and their x coordinate:

To get the height or y value we use .get_height() function and to get the x value we use .get_x(). We should also get the width so that we know where the center of each bar is.

OK, so we do have the texts but they are looking weird. We have to give them some breathing room and some formatting. We will use the offset text feature we talked earlier:

There you go, you have the height of each bar placed on top. It took some work to get to the right conditions so I suggest you reread this section and practice it on your own.

I am planning to write a separate article about annotating text since it is a big topic and needs some time to wrap your head around. I will probably be talking about more advanced methods for placing text and also discuss more plot types, using arrows, etc. So, stay tuned folks.