Coverage for C:\Users\t590r\Documents\GitHub\suppy\suppy\utils\plot.py: 0%

55 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2025-02-05 10:12 +0100

1from itertools import cycle 

2import numpy as np 

3 

4import numpy.typing as npt 

5import matplotlib.pyplot as plt 

6 

7 

8def plot2d_linear_constraints(x: npt.NDArray, A: npt.NDArray, lb: npt.NDArray, ub: npt.NDArray): 

9 """ 

10 Plots the linear 2d constraints defined by lb <= A_0*x+A_1*y <= ub. 

11 

12 Parameters: 

13 x (array-like): The x-values for the plot. 

14 A (array-like): The coefficient matrix of the linear constraints. 

15 lb (array-like): The lower bounds of the constraints. 

16 ub (array-like): The upper bounds of the constraints. 

17 

18 Returns: 

19 None 

20 """ 

21 plt.figure() 

22 ax = plt.gca() 

23 

24 color_cycle = cycle(plt.cm.tab10.colors) 

25 for i in range(A.shape[0]): 

26 color = next(color_cycle) 

27 if A[i, 1] == 0: 

28 ax.axvline(x=-lb[i] / A[i, 0], label=f"Constraint {i}", color=color) 

29 ax.axvline(x=-ub[i] / A[i, 0], label=f"Constraint {i}", color=color) 

30 else: 

31 y = (lb[i] - A[i, 0] * x) / A[i, 1] 

32 ax.plot(x, y, label=f"Constraint {i}", color=color) 

33 y = (ub[i] - A[i, 0] * x) / A[i, 1] 

34 ax.plot(x, y, label=f"Constraint {i}", color=color) 

35 ax.set_ylim(-2, 2) 

36 ax.legend() 

37 return plt.gca() 

38 

39 

40def get_linear_constraint_bounds(x: npt.NDArray, A: npt.NDArray, lb: npt.NDArray, ub: npt.NDArray): 

41 """ 

42 For a given 1D array x and linear constraints defined by lb <= 

43 A_0*x+A_1*y <= ub, this function returns the associated y values. 

44 

45 Parameters: 

46 x (npt.NDArray): Array-like object representing the x values. 

47 A (npt.NDArray): Array-like object representing the coefficients of the linear constraints. 

48 lb (npt.NDArray): Array-like object representing the lower bounds of the constraints. 

49 ub (npt.NDArray): Array-like object representing the upper bounds of the constraints. 

50 

51 Returns: 

52 x_all (npt.NDArray): Array-like object with size (len(x), len(lb)*2) storing all x values for all constraints (lower and upper bounds) 

53 y_all (npt.NDArray): Array-like object storing all associated y values 

54 """ 

55 y_l = (lb - A[:, 0] * x[:, None]) / A[ 

56 :, 1 

57 ] # gives a nxm matrix with n = len(x) and m = len(lb) 

58 y_u = (ub - A[:, 0] * x[:, None]) / A[:, 1] 

59 

60 x_all = np.tile( 

61 x, (A.shape[0] * 2, 1) 

62 ).T # get a x matrix that stores all x values for all constraints 

63 return x_all, np.concatenate((y_l, y_u), axis=1) 

64 

65 

66def plot3d_linconstrained_function(func, A, x, lb, ub, func_args=()): 

67 """ 

68 For given x values finds the associated y values (giving the linear 

69 constrained bounds) 

70 and plots the 2D surface of a function with linear constraints. 

71 

72 Parameters: 

73 A (npt.NDArray): Array-like object representing the coefficients of the linear constraints. 

74 x (npt.NDArray): Array-like object representing the x values. 

75 lb (npt.NDArray): Array-like object representing the lower bounds of the constraints. 

76 ub (npt.NDArray): Array-like object representing the upper bounds 

77 """ 

78 x_1, x_2 = get_linear_constraint_bounds(x, A, lb, ub) 

79 

80 x_reshaped = np.reshape( 

81 np.array([x_1, x_2]), (2, x_1.shape[0] * x_1.shape[1]) 

82 ) # reshape the array to be able to multiply with A 

83 y = func(x_reshaped, *func_args).reshape(x_1.shape[0], x_1.shape[1]) 

84 

85 fig = plt.figure() 

86 ax = fig.add_subplot(111, projection="3d") 

87 

88 for i in range(x_1.shape[1]): 

89 ax.plot(x_1[:, i], x_2[:, i], y[:, i], color="xkcd:black") 

90 

91 x_grid = np.linspace(np.min(x_1), np.max(x_1), 100) 

92 y_grid = np.linspace(np.min(x_2), np.max(x_2), 100) 

93 X, Y = np.meshgrid(x_grid, y_grid) 

94 Z = func(np.array([X, Y]).reshape(2, -1)).reshape(X.shape[0], X.shape[1]) 

95 ax.plot_surface(X, Y, Z, cmap="plasma", alpha=0.2) 

96 ax.set_xlabel("x$_1$") 

97 ax.set_ylabel("x$_2$") 

98 ax.set_xlim(np.min([np.min(x_1), np.min(x_2)]), np.max([np.max(x_1), np.max(x_2)])) 

99 ax.set_ylim(np.min([np.min(x_1), np.min(x_2)]), np.max([np.max(x_1), np.max(x_2)])) 

100 return fig, ax 

101 

102 

103def plot3d_general_objects(func, objects, func_args=(), x: None | npt.NDArray = None): 

104 """PLots a 3D function with multiple objects.""" 

105 fig = plt.figure() 

106 ax = fig.add_subplot(111, projection="3d") 

107 

108 for el in objects: 

109 xy = el.get_xy() # should return a 2xn array 

110 ax.plot(xy[0, :], xy[1, :], func(xy, *func_args), color="xkcd:black") 

111 

112 if x is None: 

113 x = np.linspace(-10, 10, 100) 

114 

115 X, Y = np.meshgrid(x, x) 

116 Z = func(np.array([X, Y]).reshape(2, -1), *func_args).reshape(X.shape[0], X.shape[1]) 

117 ax.plot_surface(X, Y, Z, cmap="plasma", alpha=0.2) 

118 

119 return fig, ax 

120 

121 

122# if __name__ == "__main__": 

123# #Importing some libraries 

124# import numpy as np 

125# import matplotlib.pyplot as plt 

126# import suppy.projections as pr 

127# import suppy.superiorization.sup as sup 

128 

129# center_1 = np.array([0,0]) 

130# radius = 1 

131# center_2 = np.array([1,1]) 

132 

133# center_3 = np.array([1.5,0]) 

134 

135# #Creating a circle 

136 

137# Ball_1 = pr.Ball_Projection(center_1, radius) 

138# Ball_2 = pr.Ball_Projection(center_2, radius) 

139 

140# def func_1(x): 

141# return 1/len(x)*(x**2).sum(axis=0) 

142 

143# def grad_1(x): 

144# return 1/len(x)*2*x 

145 

146# Proj = pr.Sequential_Projection([Ball_1,Ball_2]) 

147 

148# Test = sup.Standard_superiorize(Proj,func_1,grad_1) 

149 

150# xF = Test.solve(np.array([1,3]),1,10,storage=True) 

151# X = np.array(Test.all_X_values) 

152 

153# fig,ax = plot3d_generalObjects(func_1,[Ball_1,Ball_2],x=np.linspace(-3,3,50)) 

154# ax.plot(X[:,0],X[:,1],Test.all_function_values) 

155# plt.show()