13

Is it possible to display each point's value next to it on chart diagram:

Chart

Values shown on points are: [7, 57, 121, 192, 123, 240, 546]

values = list(map(lambda x: x[0], result)) #[7, 57, 121, 192, 123, 240, 546]
labels = list(map(lambda x: x[1], result)) #['1950s', '1960s', '1970s', '1980s', '1990s', '2000s', '2010s']

plt.plot(labels, values, 'bo')
plt.show()

Here's my current code for this chart.

I would like to know each point value shown on graph, currently I can only predict values based on y-axis.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
Lululu
  • 675
  • 3
  • 9
  • 21

3 Answers3

18

Based on your values, here is one solution using plt.text

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
values = [7, 57, 121, 192, 123, 240, 546]
labels = ['1950s', '1960s', '1970s', '1980s', '1990s', '2000s', '2010s']

plt.plot(range(len(labels)), values, 'bo') # Plotting data
plt.xticks(range(len(labels)), labels) # Redefining x-axis labels

for i, v in enumerate(values):
    ax.text(i, v+25, "%d" %v, ha="center")
plt.ylim(-10, 595)
plt.show()

Output

enter image description here

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
Sheldore
  • 37,862
  • 7
  • 57
  • 71
8

Solution based on plt.annotate

fig = plt.figure()
ax = fig.add_subplot(111)
values = [7, 57, 121, 192, 123, 240, 546]
labels = ['1950s', '1960s', '1970s', '1980s', '1990s', '2000s', '2010s']

plt.plot(range(len(labels)), values, 'bo') # Plotting data
plt.xticks(range(len(labels)), labels) # Redefining x-axis labels

for i, v in enumerate(values):
    ax.annotate(str(v), xy=(i,v), xytext=(-7,7), textcoords='offset points')
plt.ylim(-10, 595)

Output:

enter image description here

Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
Pierre Louis
  • 308
  • 2
  • 11
0

Alright, for anyone needing something a little more complicated, here's an extension of @Sheldore's answer on my own data:

How to plot the (x, y) text for each point using plt.text(), and handle the first and last points with custom text formatting:

Here's the gist of it:

# generalized form
plt.text(x_loc, y_loc, f"my label", horizontalalignment="left|center|right")

# example
plt.text(x+.2, y, f"({x} KiB, {y:.0f} MB/sec)", horizontalalignment="left")

See the official matplotlib.pyplot.text() documentation here: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.text.html

Full, runnable example:

import matplotlib.pyplot as plt

from statistics import mean

# cluster size (KiB) vs speed (MB/s)
x_cluster_size = [0.5, 4, 8, 32, 128, 32768]
y_speed = [
    mean([87.36, 96.84]),
    mean([285.36, 352.37, 309.35]),
    mean([333.19, 320.87, 360.62]),
    mean([360.59, 329.26, 387.60]),
    mean([392.01, 363.88, 413.63]),
    mean([437.09, 409.12, 436.98]),
]
plt.plot(x_cluster_size, y_speed, 'b-o', label='When writing a 5.3 GB file')
plt.legend(loc='lower right')
plt.xscale('log', base=2)
plt.ylabel('Speed (MB/sec)')
plt.xlabel('exFAT cluster size (KiB)')
plt.title("exFAT cluster size vs speed")
# display (x, y) values next to each point
for i, x in enumerate(x_cluster_size):
    y = y_speed[i]
    # first element
    if i == 0:
        plt.text(x+.2, y, f"({x} KiB, {y:.0f} MB/sec)", horizontalalignment="left")
    # last element
    elif i == len(x_cluster_size) - 1:
        plt.text(x-10000, y, f"({x} KiB, {y:.0f} MB/sec)", horizontalalignment="right")
    else:
        plt.text(x, y-20, f"({x} KiB, {y:.0f} MB/sec)", horizontalalignment="left")
plt.show()

enter image description here

To go further, and add figure super titles, subtitles, footers, etc, see my other answer here.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265