user1821176
user1821176

Reputation: 1191

Plot vertical arrows for my points

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 )

enter image description here

Upvotes: 1

Views: 4140

Answers (4)

tacaswell
tacaswell

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

demo image

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

Diziet Asahi
Diziet Asahi

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)

enter image description here

Upvotes: 3

Paul H
Paul H

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="<|-"))

enter image description here

Upvotes: 3

Kyler Brown
Kyler Brown

Reputation: 1126

This is bit hacky, adjust arrow_offset and arrow_size until the figure looks right.enter image description here

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

Related Questions