Matplotlib/pyplot: easy way for conditional formatting of linestyle?

1.3k views Asked by At

Let's say I want to plot two solid lines that cross each other and I want to plot line2 dashed only if it is above line 1. The lines are on the same x-grid. What is the best/simplest way to achieve this? I could split the data of line2 into two corresponding arrays before I plot, but I was wondering if there is a more direct way with some kind of conditional linestyle formatting?

Minimal Example:

import numpy as np
import matplotlib.pyplot as plt

x  = np.arange(0,5,0.1)
y1 = 24-5*x
y2 = x**2

plt.plot(x,y1)
plt.plot(x,y2)#dashed if y2 > y1?!
plt.show()

Minimal Example

There were related questions for more complex scenarios, but I am looking for the easiest solution for this standard case. Is there a way to do this directly inside plt.plot()?

2

There are 2 answers

1
Sameeresque On BEST ANSWER

enter image description here You could try something like this:

import numpy as np
import matplotlib.pyplot as plt

x  = np.arange(0,5,0.1)
y1 = 24-5*x
y2 = x**2

xs2=x[y2>y1]
xs1=x[y2<=y1]
plt.plot(x,y1)
plt.plot(xs1,y2[y2<=y1])
plt.plot(xs2,y2[y2>y1],'--')#dashed if y2 > y1?!
plt.show()
0
Filip On

@Sameeresque solved it nicely.

This was my take:

import numpy as np
import matplotlib.pyplot as plt

def intersection(list_1, list_2):
    shortest = list_1 if len(list_1) < len(list_2) else list_2
    indexes = []
    for i in range(len(shortest)):
        if list_1[i] == list_2[i]:
            indexes.append(i)
    return indexes


plt.style.use("fivethirtyeight")

x  = np.arange(0, 5, 0.1)
y1 = 24 - 5*x
y2 = x**2
intersection_point = intersection(y1, y2)[0]  # In your case they only intersect once


plt.plot(x, y1)

x_1 = x[:intersection_point+1]
x_2 = x[intersection_point:]
y2_1 = y2[:intersection_point+1]
y2_2 = y2[intersection_point:]

plt.plot(x_1, y2_1)
plt.plot(x_2, y2_2, linestyle="dashed")

plt.show()

Same princile as @Sammeresque, but I think his solution is simpler.

preview