0

I´m developing a scrip that returns a plot with the maximum values of 4 equations. However the way I did it, the value of the maximum point, for each equation, is shown in a spot where is not easy to read. How can I put the legend more to the right or left?

Code:

import math as mt
import numpy as np
import matplotlib.pyplot as plt
  
v = 20 #(Vão em metros)
h = 6 #("Altura do pilar em metros:")
ht = 8 #("Altura total metros:")
alfa_rad = mt.atan((int(ht)-int(h))/(int(v)/2))
alfa_deg = alfa_rad*180/mt.pi
lasna = ((v/2) ** 2 + (ht-h) ** 2) ** 0.5

alfa = (mt.atan((int(ht)-int(h))/(int(v)/2)))*180/((mt.pi))



h1 = np.arange(0, h+1, 1)
ha1 = np.arange(0, lasna, 0.1)
ha2 = np.arange(0, lasna, 0.1)
hp2 = np.arange(0, h+1, 1)

R = lambda x, y, theta: np.array([
    [np.cos(theta), np.sin(theta), x],
    [-np.sin(theta), np.cos(theta), y],
    [0, 0, 1],
])
Vx = np.array([
    [1, 0, 0], [0, -1, 0], [0, 0, 1]
])
Vy = np.array([
    [-1, 0, 0], [0, 1, 0], [0, 0, 1]
])
vpilar1 = (1000 * h1 ** 2 + 50)/ 1000
vasna1 = (50 *ha1 ** 2 + 5) / 1000
vasna2 = (100 * ha2 ** 2 + 7) / 1000
vpilar2 = (150 * hp2 ** 2 + 5) / 1000

def draw_line():
    fig, ax = plt.subplots()
    
    x_number_list = [0, 0, (v/2), v, v]
    y_number_list = [0, h, ht, h, 0]
    plt.plot(x_number_list, y_number_list, linewidth=3)
    
    
    points1 = np.stack([h1, vpilar1 / max(abs(vpilar1)), np.ones_like(h1)])
    points1 = np.matmul(R(0, 0, -np.pi/2), points1)
    plt.plot(points1[0, :], points1[1, :], label="Vpilar1")
    idx = np.argmax(vpilar1)
    max_p = np.array([[h1[idx], (vpilar1 / max(abs(vpilar1)))[idx], 1]]).T
    max_p_tranformed = np.matmul(R(0, 0, -np.pi/2), max_p)
    plt.text(*max_p_tranformed[:-1], str(vpilar1[idx]))
    plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
      
    
    points2 = np.stack([h1, vpilar2 / max(abs(vpilar2)), np.ones_like(h1)])
    points2 = np.matmul(R(v, 0, -np.pi/2), points2)
    plt.plot(points2[0, :], points2[1, :], label="Vpilar2")
    idx = np.argmax(vpilar2)
    max_p = np.array([[h1[idx], (vpilar2 / max(abs(vpilar2)))[idx], 1]]).T
    max_p_tranformed = np.matmul(R(v, 0, -np.pi/2),  max_p)
    plt.text(*max_p_tranformed[:-1], str(vpilar2[idx]))
    plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
    
    
    points3 = np.stack([ha1, vasna1 / max(abs(vasna1)), np.ones_like(ha1)])
    points3 = np.matmul(R(0, h, -alfa_rad), points3)
    plt.plot(points3[0, :], points3[1, :], label="Vasna1")
    idx = np.argmax(vasna1)
    max_p = np.array([[ha1[idx], (vasna1 / max(abs(vasna1)))[idx], 1]]).T
    max_p_tranformed = np.matmul(R(0, h, -alfa_rad), max_p)
    plt.text(*max_p_tranformed[:-1], str(vasna1[idx]))
    plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
    
    points4 = np.stack([ha1, vasna2 / max(abs(vasna2)), np.ones_like(ha1)])
    points4 = np.matmul(np.matmul(R(v, h, alfa_rad), Vy), points4)
    plt.plot(points4[0, :], points4[1, :], label="Vasna2")
    idx = np.argmax(vasna2)
    max_p = np.array([[ha1[idx], (vasna2 / max(abs(vasna2)))[idx], 1]]).T
    max_p_tranformed = np.matmul(np.matmul(R(v, h, alfa_rad), Vy), max_p)
    plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
    
    plt.title("Esforço de Corte (kN)", fontsize=15)
    plt.show()

draw_line()

PS: I´m a nobbie in SO, so unfornately I can´t show the plot.

amotoli
  • 39
  • 7
  • Does [Move and resize legends-box in matplotlib](https://stackoverflow.com/questions/23238041/move-and-resize-legends-box-in-matplotlib) answer your question? Or [How to specify legend position in matplotlib in graph coordinates](https://stackoverflow.com/questions/44413020/how-to-specify-legend-position-in-matplotlib-in-graph-coordinates)? – wwii May 18 '22 at 17:45
  • I allready tried the answers on this questions, but they do it for one equation, not 4. I'm not sure how to make it work it for mine script. – amotoli May 18 '22 at 17:57

1 Answers1

0

The plt.text in the draw_line() function is the part of code responsible for writing the text with the max values. In your code, it is there for just 3, think you removed the 4th one as it was on top of the other. The location (x and y coordinates) of the text is controlled by the first variable. You need to add some extra spaces to move the text to where you want. Below are the updated 4 lines of code. If you make the changes to your code, you should be able to see the text move.

plt.text(*max_p_tranformed[:-1][0]+0.1, *max_p_tranformed[:-1][1]+0.2, str(vpilar1[idx]))

....

plt.text(*max_p_tranformed[:-1][0]+0.1, *max_p_tranformed[:-1][1]+0.3, str(vpilar2[idx]))

....

plt.text(*max_p_tranformed[:-1][0]-7.3, *max_p_tranformed[:-1][1]+0.1, str(vasna1[idx]))

....

plt.text(*max_p_tranformed[:-1][0]+0.1, *max_p_tranformed[:-1][1]+0.1, str(vasna2[idx]))

The graph looks like this. Change the deltas (+0.1, +0.2, etc.) to see the text move up/down or left/right.

Output graph with these adjustments

enter image description here

Redox
  • 9,321
  • 5
  • 9
  • 26
  • Glad it resolved the problem. If this answered the question, pls accept answer by clicking on tick mark to close the question – Redox May 19 '22 at 19:54
  • is it possible to round the value of vasna1 and vasna2? – amotoli May 19 '22 at 19:55
  • Just add ````round(..., 2)```` like this example - ```` plt.text(*max_p_tranformed[:-1][0]+0.1, *max_p_tranformed[:-1][1]+0.1, str(round(vasna2[idx], 3)))```` – Redox May 19 '22 at 20:00
  • i was not sure if I could put the round() inside the str(). – amotoli May 19 '22 at 20:02