1

The standard code for plotting lines from a point would be something like the following:

import numpy as np
from matplotlib import pyplot as plt

def plot_tangents(x, y, tangents):
    plt.plot(x, y, 'b.')
    # set xlim/ylim
    plt.xlim([min(x)-50, max(x)+50])
    plt.ylim([min(y)-50, max(y)+50])

    for i, m in enumerate(tangents):
        tx = np.linspace(x[i] - 5, x[i] + 5)
        plt.plot(tx, m*(tx - x[i]) + y[i], 'r--', label=f"y={m}(x - {x[i]} + {y[i]}")
        
    plt.show()

# Working example
dummyx = np.linspace(50, 100)
dummyy = np.linspace(50, 100)
dummym = np.linspace(1, 1)
plot_tangents(dummyx, dummyy, dummym)

# Failing example
dummyx = np.linspace(50, 50)
dummyy = np.linspace(200, 550)
dummym = np.array([np.inf] * 50)
plot_tangents(dummyx, dummyy, dummym)

However when given vertical lines with linspace in x or horizontal lines with linspace in y, this code will fail to plot.

Is there anyway to get matplot to handle these cases - ideally I'd like to plot a limited segment length for the tangent rather than an x/y range.

Expected tangents forming the line

Missing vertical line, no plot visible (which makes sense from the equation)

Partial Solution

The missing vertical line can be fixed with the following change to the line plot code - thanks @tdy - but understandably this is now an infinite line tangent.

plt.axline(xy1=(x[i], y[i]), slope=m, label=f'$y {-y[i]:+} = {m}(x {-x[i]:+})$')
  • The intention is to plot the tangents along the given points; normally these tangents are calculated separately but wanted to given a simple example without the tangent calculation. – Daniel Hails Feb 14 '22 at 18:59
  • Good point about the `linspace` - just was meant to be a quick way to mirror the expected gradients without calculating them (which is done in a separate process that is working correctly). – Daniel Hails Feb 14 '22 at 19:03
  • 2
    it looks like you're trying to plot a `y = m*x + b` line, so it's easiest to use `axline`: https://stackoverflow.com/a/71090008/13138364 – tdy Feb 14 '22 at 19:10
  • @tdy Great! That works now: `plt.axline(xy1=(x[i], y[i]), slope=m, label=f'$y {-y[i]:+} = {m}(x {-x[i]:+})$')` Is there anyway to limit the line length without reference to x / y - e.g. using euclidean length. Otherwise vertical lines are unbounded in xmin / xmax. – Daniel Hails Feb 14 '22 at 19:18
  • `axline` is just for infinite lines, so if you want a bounded version, i guess you would still need `plot`. i'm a bit confused by the examples though. normally you'd want to plot tangents against some curve, right? so for every point of a given curve, are you trying to plot a tangent line measuring 5 units to either side of that point? – tdy Feb 14 '22 at 19:56
  • Pretty much - it's basically designed to visually demonstrate that the tangent code works. The omitted step is that the tangent plots are bounded to a small region of the curve (to make it less cluttered). – Daniel Hails Feb 15 '22 at 17:56

0 Answers0