14
14
from ..mobject .number_line import NumberLine
15
15
from ..mobject .svg .tex_mobject import MathTex
16
16
from ..mobject .types .vectorized_mobject import VGroup
17
- from ..utils .config_ops import merge_dicts_recursively
17
+ from ..utils .config_ops import merge_dicts_recursively , update_dict_recursively
18
18
from ..utils .simple_functions import binary_search
19
19
from ..utils .space_ops import angle_of_vector
20
20
from ..utils .color import LIGHT_GREY , WHITE , BLUE_D , BLUE
@@ -28,16 +28,12 @@ class CoordinateSystem:
28
28
Abstract class for Axes and NumberPlane
29
29
"""
30
30
31
- def __init__ (self , dim = 2 ):
31
+ def __init__ (self , x_min = None , x_max = None , y_min = None , y_max = None , dim = 2 ):
32
32
self .dimension = dim
33
- if not hasattr (self , "x_min" ):
34
- self .x_min = - config ["frame_x_radius" ]
35
- if not hasattr (self , "x_max" ):
36
- self .x_max = config ["frame_x_radius" ]
37
- if not hasattr (self , "y_min" ):
38
- self .y_min = - config ["frame_y_radius" ]
39
- if not hasattr (self , "y_max" ):
40
- self .y_max = config ["frame_y_radius" ]
33
+ self .x_min = - config ["frame_x_radius" ] if x_min is None else x_min
34
+ self .x_max = config ["frame_x_radius" ] if x_max is None else x_max
35
+ self .y_min = - config ["frame_y_radius" ] if y_min is None else y_min
36
+ self .y_max = config ["frame_y_radius" ] if y_max is None else y_max
41
37
42
38
def coords_to_point (self , * coords ):
43
39
raise NotImplementedError ()
@@ -132,43 +128,56 @@ def input_to_graph_point(self, x, graph):
132
128
class Axes (VGroup , CoordinateSystem ):
133
129
def __init__ (
134
130
self ,
131
+ x_min = None ,
132
+ x_max = None ,
133
+ y_min = None ,
134
+ y_max = None ,
135
135
axis_config = None ,
136
136
x_axis_config = None ,
137
- y_axis_config = { "label_direction" : LEFT } ,
137
+ y_axis_config = None ,
138
138
center_point = ORIGIN ,
139
139
** kwargs
140
140
):
141
- if axis_config is None :
142
- axis_config = {
143
- "color" : LIGHT_GREY ,
144
- "include_tip" : True ,
145
- "exclude_zero_from_default_numbers" : True ,
146
- }
147
- self .axis_config = axis_config
148
- if x_axis_config is None :
149
- x_axis_config = {}
150
- self .x_axis_config = x_axis_config
151
- self .y_axis_config = y_axis_config
152
- self .center_point = center_point
153
- CoordinateSystem .__init__ (self )
141
+ CoordinateSystem .__init__ (
142
+ self , x_min = x_min , x_max = x_max , y_min = y_min , y_max = y_max
143
+ )
154
144
VGroup .__init__ (self , ** kwargs )
155
- self .x_axis = self .create_axis (self .x_min , self .x_max , self .x_axis_config )
156
- self .y_axis = self .create_axis (self .y_min , self .y_max , self .y_axis_config )
157
- self .y_axis .rotate (90 * DEGREES , about_point = ORIGIN )
145
+
146
+ self .axis_config = {
147
+ "color" : LIGHT_GREY ,
148
+ "include_tip" : True ,
149
+ "exclude_zero_from_default_numbers" : True ,
150
+ }
151
+ self .x_axis_config = {"x_min" : self .x_min , "x_max" : self .x_max }
152
+ self .y_axis_config = {
153
+ "x_min" : self .y_min ,
154
+ "x_max" : self .y_max ,
155
+ "label_direction" : LEFT ,
156
+ "rotation" : 90 * DEGREES ,
157
+ }
158
+
159
+ self .update_default_configs (
160
+ (self .axis_config , self .x_axis_config , self .y_axis_config ),
161
+ (axis_config , x_axis_config , y_axis_config ),
162
+ )
163
+ self .center_point = center_point
164
+ self .x_axis = self .create_axis (self .x_axis_config )
165
+ self .y_axis = self .create_axis (self .y_axis_config )
158
166
# Add as a separate group in case various other
159
167
# mobjects are added to self, as for example in
160
168
# NumberPlane below
161
169
self .axes = VGroup (self .x_axis , self .y_axis , dim = self .dim )
162
170
self .add (* self .axes )
163
171
self .shift (self .center_point )
164
172
165
- def create_axis (self , min_val , max_val , axis_config ):
166
- new_config = merge_dicts_recursively (
167
- self .axis_config ,
168
- {"x_min" : min_val , "x_max" : max_val },
169
- axis_config ,
170
- )
171
- return NumberLine (** new_config )
173
+ @staticmethod
174
+ def update_default_configs (default_configs , passed_configs ):
175
+ for default_config , passed_config in zip (default_configs , passed_configs ):
176
+ if passed_config is not None :
177
+ update_dict_recursively (default_config , passed_config )
178
+
179
+ def create_axis (self , axis_config ):
180
+ return NumberLine (** merge_dicts_recursively (self .axis_config , axis_config ))
172
181
173
182
def coords_to_point (self , * coords ):
174
183
origin = self .x_axis .number_to_point (0 )
@@ -208,37 +217,33 @@ def add_coordinates(self, x_vals=None, y_vals=None):
208
217
class ThreeDAxes (Axes ):
209
218
def __init__ (
210
219
self ,
211
- z_axis_config = None ,
212
- z_min = - 3.5 ,
213
- z_max = 3.5 ,
214
220
x_min = - 5.5 ,
215
221
x_max = 5.5 ,
216
222
y_min = - 5.5 ,
217
223
y_max = 5.5 ,
224
+ z_min = - 3.5 ,
225
+ z_max = 3.5 ,
226
+ z_axis_config = None ,
218
227
z_normal = DOWN ,
219
228
num_axis_pieces = 20 ,
220
229
light_source = 9 * DOWN + 7 * LEFT + 10 * OUT ,
221
230
** kwargs
222
231
):
223
- if z_axis_config is None :
224
- z_axis_config = {}
225
- self . z_axis_config = z_axis_config
232
+ Axes . __init__ (
233
+ self , x_min = x_min , x_max = x_max , y_min = y_min , y_max = y_max , ** kwargs
234
+ )
226
235
self .z_min = z_min
227
236
self .z_max = z_max
237
+ self .z_axis_config = {"x_min" : self .z_min , "x_max" : self .z_max }
238
+ self .update_default_configs ((self .z_axis_config ,), (z_axis_config ,))
228
239
self .z_normal = z_normal
229
240
self .num_axis_pieces = num_axis_pieces
230
241
self .light_source = light_source
231
- self .x_min = x_min
232
- self .x_max = x_max
233
- self .y_min = y_min
234
- self .y_max = y_max
235
- Axes .__init__ (self , ** kwargs )
236
242
self .dimension = 3
237
- z_axis = self .z_axis = self .create_axis (
238
- self .z_min , self .z_max , self .z_axis_config
239
- )
240
- z_axis .rotate (- np .pi / 2 , UP , about_point = ORIGIN )
241
- z_axis .rotate (angle_of_vector (self .z_normal ), OUT , about_point = ORIGIN )
243
+ z_axis = self .z_axis = self .create_axis (self .z_axis_config )
244
+ z_axis .shift (self .center_point )
245
+ z_axis .rotate_about_zero (- np .pi / 2 , UP )
246
+ z_axis .rotate_about_zero (angle_of_vector (self .z_normal ))
242
247
self .axes .add (z_axis )
243
248
self .add (z_axis )
244
249
@@ -280,28 +285,26 @@ def __init__(
280
285
make_smooth_after_applying_functions = True ,
281
286
** kwargs
282
287
):
283
- if axis_config is None :
284
- axis_config = {
285
- "stroke_color" : WHITE ,
286
- "stroke_width" : 2 ,
287
- "include_ticks" : False ,
288
- "include_tip" : False ,
289
- "line_to_number_buff" : SMALL_BUFF ,
290
- "label_direction" : DR ,
291
- "number_scale_val" : 0.5 ,
292
- }
293
- self .axis_config = axis_config
294
- if y_axis_config is None :
295
- y_axis_config = {"label_direction" : DR }
296
- self .y_axis_config = y_axis_config
297
-
298
- if background_line_style is None :
299
- background_line_style = {
300
- "stroke_color" : BLUE_D ,
301
- "stroke_width" : 2 ,
302
- "stroke_opacity" : 1 ,
303
- }
304
- self .background_line_style = background_line_style
288
+ self .axis_config = {
289
+ "stroke_color" : WHITE ,
290
+ "stroke_width" : 2 ,
291
+ "include_ticks" : False ,
292
+ "include_tip" : False ,
293
+ "line_to_number_buff" : SMALL_BUFF ,
294
+ "label_direction" : DR ,
295
+ "number_scale_val" : 0.5 ,
296
+ }
297
+ self .y_axis_config = {"label_direction" : DR }
298
+ self .background_line_style = {
299
+ "stroke_color" : BLUE_D ,
300
+ "stroke_width" : 2 ,
301
+ "stroke_opacity" : 1 ,
302
+ }
303
+
304
+ self .update_default_configs (
305
+ (self .axis_config , self .y_axis_config , self .background_line_style ),
306
+ (axis_config , y_axis_config , background_line_style ),
307
+ )
305
308
306
309
# Defaults to a faded version of line_config
307
310
self .faded_line_style = faded_line_style
0 commit comments