Reputation: 1191
I am trying to figure out a way to add a vertical arrow pointing up for each of my data points. I have scatter plot and code below. I need the vertical arrows to start from the points going upwards to a length of about 0.2 in th graph scale.
import matplotlib.pyplot as plt
fig = plt.figure()
a1 = fig.add_subplot(111)
simbh = np.array([5.3, 5.3, 5.5, 5.6, 5.6, 5.8, 5.9, 6.0, 6.2, 6.3, 6.3])
simstel =np.array([10.02, 10.08, 9.64, 9.53, 9.78, 9.65, 10.05, 10.09, 10.08, 10.22, 10.42])
sca2=a1.scatter(simstel, simbh )
Upvotes: 1
Views: 4140
Reputation: 87376
This can be done directly
from matplotlib import pyplot as plt
import numpy as np
# set up figure
fig, ax = plt.subplots()
# make synthetic data
x = np.linspace(0, 1, 15)
y = np.random.rand(15)
yerr = np.ones_like(x) * .2
# if you are using 1.3.1 or older you might need to use uplims to work
# around a bug, see below
ax.errorbar(x, y, yerr=yerr, lolims=True, ls='none', marker='o')
# adjust axis limits
ax.margins(.1) # margins makes the markers not overlap with the edges
There was some strangeness in how these arrows are implemented where the semantics changed so that 'lolims' means 'the data point is the lower limit' and 'uplims' means 'the data point is the maximum value'.
See https://github.com/matplotlib/matplotlib/pull/2452
Upvotes: 3
Reputation: 40697
This is not super elegant, but it does the trick
to get the arrows start at the data point and go up 0.2 units:
for x,y in zip(simstel,simbh):
plt.arrow(x,y,0,0.2)
Upvotes: 3
Reputation: 68146
The other approaches presented are great. I'm going for the hackiest award today:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
simbh = np.array([5.3, 5.3, 5.5, 5.6, 5.6, 5.8, 5.9, 6.0, 6.2, 6.3, 6.3])
simstel = np.array([10.02, 10.08, 9.64, 9.53, 9.78, 9.65, 10.05, 10.09, 10.08, 10.22, 10.42])
sca2 = ax.scatter(simstel, simbh)
for x, y in zip(simstel, simbh):
ax.annotate('', xy=(x, y), xytext=(0, 25), textcoords='offset points',
arrowprops=dict(arrowstyle="<|-"))
Upvotes: 3
Reputation: 1126
This is bit hacky, adjust arrow_offset
and arrow_size
until the figure looks right.
import matplotlib.pyplot as plt
fig = plt.figure()
a1 = fig.add_subplot(111)
simbh = np.array([5.3, 5.3, 5.5, 5.6, 5.6, 5.8, 5.9, 6.0, 6.2, 6.3, 6.3])
simstel =np.array([10.02, 10.08, 9.64, 9.53, 9.78, 9.65, 10.05, 10.09, 10.08, 10.22, 10.42])
sca2=a1.scatter(simstel, simbh, c='w' )
arrow_offset = 0.08
arrow_size = 500
sca2=a1.scatter(simstel, simbh + arrow_offset,
marker=r'$\uparrow$', s=arrow_size)
Upvotes: 4