user13412850
user13412850

Reputation: 519

Shading the area of a triangle

This is my code:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

x = np.random.randint(1,100,100)
y = np.random.randint(-500,200,100)
plt.scatter(x, y)
ax = plt.gca()
ax.invert_yaxis()


x1, y1 = [0, 100], [-200, 0]
x2, y2 = [0, 0], [0, -200]
x3, y3 = [0, 100], [0, 0]

plt.plot(x1,y1,x2,y2,x3,y3, marker = 'o')
plt.show()

plt.show()

There are two issues

  1. I want the color of the arms of the triangle to be the same, how do I do that?
  2. I want to shade the area under the triangle such that it's translucent, i.e. I can see the dots of the scatter plots which are inside the triangle. Is that doable?

enter image description here

Upvotes: 1

Views: 899

Answers (3)

JohanC
JohanC

Reputation: 80299

You can represent a triangle by listing the 3 xy coordinates. Repeating the first point creates a closed polygon. Converting to numpy makes it easier to select only the x and only the y coordinates as in triangle[:,0] for the x-coordinates.

fill creates a filled polygon, where alpha brings semi-transparency.

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randint(1, 100, 100)
y = np.random.randint(-500, 200, 100)
ax = plt.gca()
ax.scatter(x, y)
ax.invert_yaxis()

points = [[0, -200], [100, 0], [0, 0]]
triangle = np.array(points + points[:1])

ax.plot(triangle[:, 0], triangle[:, 1], marker='o')
ax.fill(triangle[:, 0], triangle[:, 1], color='yellow', alpha=0.3)

for xi, yi in points:
    ax.text(xi, yi, f' x:{xi:.0f}\n y:{yi:.0f}', color='red', fontsize=12, weight='bold',
            va='top' if yi > -100 else 'bottom')
ax.set_xlim(xmax=120) # more space for text

plt.show()

filled triangle

PS: This answer uses fill as it applicable to general triangles (and also more complicated polygons). fill_between(x1, y1) fills the area between the line segment x1,y1 and y=0. As in the question's example y3 is everywhere 0, fill_between(x1, y1) will color the example triangle. If y3 had different values, but still x3 and x1 would be equal, fill_between(x1, y1, y3) would work. For a more arbitrary triangle, fill_between would be more cumbersome.

Upvotes: 1

Alejandro
Alejandro

Reputation: 3392

More generally, you can fill any polygon using matplotlib patches and collections (example):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection    

x = np.random.randint(1,100,100)
y = np.random.randint(-500,200,100)
plt.scatter(x, y)
ax = plt.gca()
ax.invert_yaxis()


vertices = np.array([[0,0],[0,-200.0],[100.0,0]])

patches = []
triangle = Polygon(vertices, True)
patches.append(triangle)

p = PatchCollection(patches, alpha=0.4)
ax=plt.gca()
ax.add_collection(p)

plt.show()

enter image description here

Upvotes: 1

meowulf
meowulf

Reputation: 377

You just need to specify the color attribute in plot(). As for the shading, you need the fill_between() function:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

x = np.random.randint(1,100,100)
y = np.random.randint(-500,200,100)

ax = plt.gca()
ax.scatter(x, y)
ax.invert_yaxis()

x1, y1 = [0, 100], [-200, 0]
x2, y2 = [0, 0], [0, -200]
x3, y3 = [0, 100], [0, 0]

ax.plot(x1,y1,x2,y2,x3,y3, marker = 'o', color='red')
ax.fill_between(x1, y1, facecolor='red', alpha=0.5)
plt.show()

Output:

Image

Upvotes: 1

Related Questions