Home > Enterprise >  Automatic add text to matplotlib plot in Python
Automatic add text to matplotlib plot in Python

Time:03-09

I try to produce a plot and want to automatically add text (in this case is percentage) to each circle in correspond to each y axis types. Any help would be very helpful.

# import libraries
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# Make some data
index=['Stream flow',
 'Soil moisture',
 'Water indices',
 'Others',
 'Temperature',
 'Precipitation',
 'Vegetative indices']
value=[2.13, 6.38, 10.64, 12.77, 17.73, 21.99, 28.37]

# create dataframe
percentages = pd.Series(value,index=index)
df = pd.DataFrame({'percentage' : percentages})
df = df.sort_values(by='percentage')

# we first need a numeric placeholder for the y axis
my_range=list(range(1,len(df.index) 1))

fig, ax = plt.subplots(figsize=(15,8))

# create for each expense type an horizontal line that starts at x = 0 with the length 
plt.hlines(y=my_range, xmin=0, xmax=df['percentage']-0.5, color='black', alpha=0.8, linewidth=1)

# create for each expense type a dot at the level of the expense percentage value
line=plt.plot(df['percentage'], my_range, "o", markersize=30, color='#fd8c00', alpha=0.6, linewidth=0.3)

# set labels
ax.set_xlabel('Percentage', fontsize=15)
ax.set_ylabel('')

# set axis
ax.tick_params(axis='both', which='major', labelsize=14)
plt.yticks(my_range, df.index)


ax.set_xlim(0,30)

CodePudding user response:

You can use enter image description here


Same code as above, but with increased circle radius and font, in order to improve readability.

# import libraries
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# Make some data
index=['Stream flow',
 'Soil moisture',
 'Water indices',
 'Others',
 'Temperature',
 'Precipitation',
 'Vegetative indices']
value=[2.13, 6.38, 10.64, 12.77, 17.73, 21.99, 28.37]

# create dataframe
percentages = pd.Series(value,index=index)
df = pd.DataFrame({'percentage' : percentages})
df = df.sort_values(by='percentage')

# we first need a numeric placeholder for the y axis
my_range=list(range(1,len(df.index) 1))

fig, ax = plt.subplots(figsize=(15,8))

# create for each expense type an horizontal line that starts at x = 0 with the length 
plt.hlines(y=my_range, xmin=0, xmax=df['percentage']-0.85, color='black', alpha=0.8, linewidth=1)

# create for each expense type a dot at the level of the expense percentage value
line=plt.plot(df['percentage'], my_range, "o", markersize=50, color='#fd8c00', alpha=0.6, linewidth=0.3)

# set labels
ax.set_xlabel('Percentage', fontsize=15)
ax.set_ylabel('')

# set axis
ax.tick_params(axis='both', which='major', labelsize=14)
plt.yticks(my_range, df.index)

ax.set_xlim(0,30)
ax.set_ylim(0, len(value)   1)

x_space = 0.75
y_space = 0.06
fontsize = 12
for y_i, val in enumerate(value, 1):
    ax.text(x = val - x_space, y = y_i - y_space, s = f'{val:>5.2f}%', fontsize = fontsize)


plt.show()

enter image description here


Even better, you can use matplotlib.axes.Axes.annotate to get rid of x_space and y_space:

fontsize = 12
for y_i, x_i in enumerate(value, 1):
    ax.annotate(f'{x_i:>5.2f}%', xy = (x_i, y_i), xytext = (0, 0), textcoords = 'offset points', ha = 'center', va = 'center', fontsize = fontsize)

You still have to adjust the fontsize to properly fit the radius of the circles.

  • Related