9

I'm trying to figure out how to draw lines with widths in data units. For example, in the following code snippet, I would want the horizontal part of the line of width 80 to always extend from the y=-40 to the y=+40 mark, and stay that way even if the limits of the coordinate system change. Is there a way to achieve this with Line2D objects in matplotlib? Any other way to get a similar effect?

from pylab import figure, gca, Line2D

figure()
ax = gca()
ax.set_xlim(-50, 50)
ax.set_ylim(-75, 75)

ax.add_line(Line2D([-50, 0, 50], [-50, 0, 0], linewidth=80))

ax.grid()

line width in screen coordinates

mvoelske
  • 347
  • 2
  • 7
  • Just to clarify: Do you mean that if the window expands you want the blue line to *still* span from about `y=-25` to `y=25` in the picture you've posted? – unutbu Feb 10 '13 at 13:53
  • @unutbu The width is set to 80, I think the OP wants it to be from -40 to 40 always. Your answer seems to be what the OP needs. – Lev Levitsky Feb 10 '13 at 14:05
  • [Here](http://stackoverflow.com/a/19397279/1681480) is a way to do it with lines of any angle, not just padding vertically... – beroe Oct 16 '13 at 18:11

2 Answers2

8

You could use fill_between:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.set_xlim(-50, 50)
ax.set_ylim(-75, 75)
x = [-50, 0, 50]
y = np.array([-50, 0, 0])

ax.fill_between(x,y-30,y+30)

ax.grid()
plt.show()

yields

enter image description here

but unlike the line generated by

ax.add_line(Line2D([-50, 0, 50], [-50, 0, 0], linewidth=80))

the vertical thickness of the line will always be constant in data coordinates.

See also link to documentation.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • +1. The call can be simplified to `ax.fill_between([-50, 50], -25, 25)` in this case, byw. – Lev Levitsky Feb 10 '13 at 14:08
  • Thanks, but that wouldn't work for lines that aren't exactly horizontal, right? I should have been more specific that I want to do this for arbitrary lines -- I'll edit my question to clarify. – mvoelske Feb 10 '13 at 14:46
  • Actually, `fill_between` works [fine with curves](http://matplotlib.org/examples/pylab_examples/fill_between_demo.html). – unutbu Feb 10 '13 at 15:03
  • Oh, brilliant! I had no idea. That does achieve exactly what I want. – mvoelske Feb 10 '13 at 15:06
  • 3
    The thickness of the line is not constant ... the height of it is. These are the same for horizontal lines, but very steep sections will be much skinnier. – askewchan Oct 16 '13 at 19:23
2

In order to draw a line with the linewidth in data units, you may want to have a look at this answer.

It uses a class data_linewidth_plot which closely resembles the plt.plot() command's signature.

l = data_linewidth_plot( x, y, ax=ax, label='some line', linewidth = 1, alpha = 0.4)

The linewidth argument is interpreted in (y-)data units.

Community
  • 1
  • 1
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712