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,44 +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
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
- if y_axis_config is None :
148
- y_axis_config = {"label_direction" : LEFT , "rotation" : 90 * DEGREES }
149
- self .axis_config = axis_config
150
- if x_axis_config is None :
151
- x_axis_config = {}
152
- self .x_axis_config = x_axis_config
153
- self .y_axis_config = y_axis_config
154
- self .center_point = center_point
155
- 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
+ )
156
144
VGroup .__init__ (self , ** kwargs )
157
- self .x_axis = self .create_axis (self .x_min , self .x_max , self .x_axis_config )
158
- self .y_axis = self .create_axis (self .y_min , self .y_max , self .y_axis_config )
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 )
159
166
# Add as a separate group in case various other
160
167
# mobjects are added to self, as for example in
161
168
# NumberPlane below
162
169
self .axes = VGroup (self .x_axis , self .y_axis , dim = self .dim )
163
170
self .add (* self .axes )
164
171
self .shift (self .center_point )
165
172
166
- def create_axis (self , min_val , max_val , axis_config ):
167
- new_config = merge_dicts_recursively (
168
- self .axis_config ,
169
- {"x_min" : min_val , "x_max" : max_val },
170
- axis_config ,
171
- )
172
- 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 ))
173
181
174
182
def coords_to_point (self , * coords ):
175
183
origin = self .x_axis .number_to_point (0 )
@@ -209,37 +217,33 @@ def add_coordinates(self, x_vals=None, y_vals=None):
209
217
class ThreeDAxes (Axes ):
210
218
def __init__ (
211
219
self ,
212
- z_axis_config = None ,
213
- z_min = - 3.5 ,
214
- z_max = 3.5 ,
215
220
x_min = - 5.5 ,
216
221
x_max = 5.5 ,
217
222
y_min = - 5.5 ,
218
223
y_max = 5.5 ,
224
+ z_min = - 3.5 ,
225
+ z_max = 3.5 ,
226
+ z_axis_config = None ,
219
227
z_normal = DOWN ,
220
228
num_axis_pieces = 20 ,
221
229
light_source = 9 * DOWN + 7 * LEFT + 10 * OUT ,
222
230
** kwargs
223
231
):
224
- if z_axis_config is None :
225
- z_axis_config = {}
226
- 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
+ )
227
235
self .z_min = z_min
228
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 ,))
229
239
self .z_normal = z_normal
230
240
self .num_axis_pieces = num_axis_pieces
231
241
self .light_source = light_source
232
- self .x_min = x_min
233
- self .x_max = x_max
234
- self .y_min = y_min
235
- self .y_max = y_max
236
- Axes .__init__ (self , ** kwargs )
237
242
self .dimension = 3
238
- z_axis = self .z_axis = self .create_axis (
239
- self .z_min , self .z_max , self .z_axis_config
240
- )
241
- z_axis .rotate (- np .pi / 2 , UP , about_point = ORIGIN )
242
- 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 ))
243
247
self .axes .add (z_axis )
244
248
self .add (z_axis )
245
249
@@ -281,28 +285,26 @@ def __init__(
281
285
make_smooth_after_applying_functions = True ,
282
286
** kwargs
283
287
):
284
- if axis_config is None :
285
- axis_config = {
286
- "stroke_color" : WHITE ,
287
- "stroke_width" : 2 ,
288
- "include_ticks" : False ,
289
- "include_tip" : False ,
290
- "line_to_number_buff" : SMALL_BUFF ,
291
- "label_direction" : DR ,
292
- "number_scale_val" : 0.5 ,
293
- }
294
- self .axis_config = axis_config
295
- if y_axis_config is None :
296
- y_axis_config = {"label_direction" : DR }
297
- self .y_axis_config = y_axis_config
298
-
299
- if background_line_style is None :
300
- background_line_style = {
301
- "stroke_color" : BLUE_D ,
302
- "stroke_width" : 2 ,
303
- "stroke_opacity" : 1 ,
304
- }
305
- 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
+ )
306
308
307
309
# Defaults to a faded version of line_config
308
310
self .faded_line_style = faded_line_style
0 commit comments