Merge 3b1b/master

This commit is contained in:
friedkeenan 2021-02-10 09:40:16 -06:00
commit 2d83cccc0a
14 changed files with 439 additions and 89 deletions

Binary file not shown.

View file

@ -5,15 +5,15 @@ After understanding the previous knowledge, we can understand more scenes.
Many example scenes are given in ``example_scenes.py``, let's start with
the simplest and one by one.
SquareToCircle
--------------
InteractiveDevlopment
---------------------
.. manim-example:: SquareToCircle
:media: ../_static/example_scenes/SquareToCircle.mp4
.. manim-example:: InteractiveDevlopment
:media: ../_static/example_scenes/InteractiveDevlopment.mp4
from manimlib.imports import *
class SquareToCircle(Scene):
class InteractiveDevlopment(Scene):
def construct(self):
circle = Circle()
circle.set_fill(BLUE, opacity=0.5)
@ -22,11 +22,45 @@ SquareToCircle
self.play(ShowCreation(square))
self.wait()
# This opens an iPython termnial where you can keep writing
# lines as if they were part of this construct method.
# In particular, 'square', 'circle' and 'self' will all be
# part of the local namespace in that terminal.
self.embed()
# Try copying and pasting some of the lines below into
# the interactive shell
self.play(ReplacementTransform(square, circle))
self.wait()
self.play(circle.animate.stretch(4, 0))
self.play(Rotate(circle, 90 * DEGREES))
self.play(circle.animate.shift(2 * RIGHT, circle.scale, 0.25))
This scene is what we wrote in :doc:`quickstart`.
No more explanation here
text = Text("""
In general, using the interactive shell
is very helpful when developing new scenes
""")
self.play(Write(text))
# In the interactive shell, you can just type
# play, add, remove, clear, wait, save_state and restore,
# instead of self.play, self.add, self.remove, etc.
# To interact with the window, type touch(). You can then
# scroll in the window, or zoom by holding down 'z' while scrolling,
# and change camera perspective by holding down 'd' while moving
# the mouse. Press 'r' to reset to the standard camera position.
# Press 'q' to stop interacting with the window and go back to
# typing new commands into the shell.
# In principle you can customize a scene to be responsive to
# mouse and keyboard interactions
always(circle.move_to, self.mouse_point)
This scene is similar to what we wrote in :doc:`quickstart`.
And how to interact has been written in the comments.
No more explanation here.
AnimatingMethods
----------------
@ -342,6 +376,177 @@ The new classes and usage in this scene are ``always_redraw()``, ``DecimalNumber
- ``.set_y()`` means to set the ordinate of the object on the screen.
- ``.add_updater()`` sets an update function for the object. For example: ``mob1.add_updater(lambda mob: mob.next_to(mob2))`` means ``mob1.next_to(mob2)`` is executed every frame.
CoordinateSystemExample
-----------------------
.. manim-example:: CoordinateSystemExample
:media: ../_static/example_scenes/CoordinateSystemExample.mp4
class CoordinateSystemExample(Scene):
def construct(self):
axes = Axes(
# x-axis ranges from -1 to 10, with a default step size of 1
x_range=(-1, 10),
# y-axis ranges from -2 to 10 with a step size of 0.5
y_range=(-2, 2, 0.5),
# The axes will be stretched so as to match the specified
# height and width
height=6,
width=10,
# Axes is made of two NumberLine mobjects. You can specify
# their configuration with axis_config
axis_config={
"stroke_color": GREY_A,
"stroke_width": 2,
},
# Alternatively, you can specify configuration for just one
# of them, like this.
y_axis_config={
"include_tip": False,
}
)
# Keyword arguments of add_coordinate_labels can be used to
# configure the DecimalNumber mobjects which it creates and
# adds to the axes
axes.add_coordinate_labels(
font_size=20,
num_decimal_places=1,
)
self.add(axes)
# Axes descends from the CoordinateSystem class, meaning
# you can call call axes.coords_to_point, abbreviated to
# axes.c2p, to associate a set of coordinates with a point,
# like so:
dot = Dot(color=RED)
dot.move_to(axes.c2p(0, 0))
self.play(FadeIn(dot, scale=0.5))
self.play(dot.animate.move_to(axes.c2p(3, 2)))
self.wait()
self.play(dot.animate.move_to(axes.c2p(5, 0.5)))
self.wait()
# Similarly, you can call axes.point_to_coords, or axes.p2c
# print(axes.p2c(dot.get_center()))
# We can draw lines from the axes to better mark the coordinates
# of a given point.
# Here, the always_redraw command means that on each new frame
# the lines will be redrawn
h_line = always_redraw(lambda: axes.get_h_line(dot.get_left()))
v_line = always_redraw(lambda: axes.get_v_line(dot.get_bottom()))
self.play(
ShowCreation(h_line),
ShowCreation(v_line),
)
self.play(dot.animate.move_to(axes.c2p(3, -2)))
self.wait()
self.play(dot.animate.move_to(axes.c2p(1, 1)))
self.wait()
# If we tie the dot to a particular set of coordinates, notice
# that as we move the axes around it respects the coordinate
# system defined by them.
f_always(dot.move_to, lambda: axes.c2p(1, 1))
self.play(
axes.animate.scale(0.75),
axes.animate.to_corner(UL),
run_time=2,
)
self.wait()
self.play(FadeOut(VGroup(axes, dot, h_line, v_line)))
# Other coordinate systems you can play around with include
# ThreeDAxes, NumberPlane, and ComplexPlane.
GraphExample
------------
.. manim-example:: GraphExample
:media: ../_static/example_scenes/GraphExample.mp4
class GraphExample(Scene):
def construct(self):
axes = Axes((-3, 10), (-1, 8))
axes.add_coordinate_labels()
self.play(Write(axes, lag_ratio=0.01, run_time=1))
# Axes.get_graph will return the graph of a function
sin_graph = axes.get_graph(
lambda x: 2 * math.sin(x),
color=BLUE,
)
# By default, it draws it so as to somewhat smoothly interpolate
# between sampled points (x, f(x)). If the graph is meant to have
# a corner, though, you can set use_smoothing to False
relu_graph = axes.get_graph(
lambda x: max(x, 0),
use_smoothing=False,
color=YELLOW,
)
# For discontinuous functions, you can specify the point of
# discontinuity so that it does not try to draw over the gap.
step_graph = axes.get_graph(
lambda x: 2.0 if x > 3 else 1.0,
discontinuities=[3],
color=GREEN,
)
# Axes.get_graph_label takes in either a string or a mobject.
# If it's a string, it treats it as a LaTeX expression. By default
# it places the label next to the graph near the right side, and
# has it match the color of the graph
sin_label = axes.get_graph_label(sin_graph, "\\sin(x)")
relu_label = axes.get_graph_label(relu_graph, Text("ReLU"))
step_label = axes.get_graph_label(step_graph, Text("Step"), x=4)
self.play(
ShowCreation(sin_graph),
FadeIn(sin_label, RIGHT),
)
self.wait(2)
self.play(
ReplacementTransform(sin_graph, relu_graph),
FadeTransform(sin_label, relu_label),
)
self.wait()
self.play(
ReplacementTransform(relu_graph, step_graph),
FadeTransform(relu_label, step_label),
)
self.wait()
parabola = axes.get_graph(lambda x: 0.25 * x**2)
parabola.set_stroke(BLUE)
self.play(
FadeOut(step_graph),
FadeOut(step_label),
ShowCreation(parabola)
)
self.wait()
# You can use axes.input_to_graph_point, abbreviated
# to axes.i2gp, to find a particular point on a graph
dot = Dot(color=RED)
dot.move_to(axes.i2gp(2, parabola))
self.play(FadeIn(dot, scale=0.5))
# A value tracker lets us animate a parameter, usually
# with the intent of having other mobjects update based
# on the parameter
x_tracker = ValueTracker(2)
f_always(
dot.move_to,
lambda: axes.i2gp(x_tracker.get_value(), parabola)
)
self.play(x_tracker.animate.set_value(4), run_time=3)
self.play(x_tracker.animate.set_value(-2), run_time=3)
self.wait()
SurfaceExample
--------------

View file

@ -0,0 +1,144 @@
What's new
==========
Usage changes of new version manim
----------------------------------
There are many changes in the new version of manim, and here are only the changes that
may have an impact at the code writing level.
Some of the changes here may not have any major impact on the use, and some changes
that affect the use are not mentioned below.
This document is for reference only, see the source code for details.
- ``Animation``
- Added ``Fade`` as the parent class of ``FadeIn`` and ``FadeOut``
- ``FadeIn`` and ``FadeOut`` can be passed in ``shift`` and ``scale`` parameters
- Deleted ``FadeInFrom, FadeInFromDown, FadeOutAndShift, FadeOutAndShiftDown, FadeInFromLarge``, these can be used ``FadeIn, FadeOut`` to achieve the same effect more easily
- Added ``FadeTransform`` to cross fade between two objects, and subclass ``FadeTransformPieces``
- Added ``CountInFrom(decimal_mob, source_number=0)`` to count ``decimal_mob`` from ``source_number`` to the current value
- ``Rotating`` can directly pass in ``angle`` and ``axis`` without writing keywords ``angle=, axis=``
- ``Rotate`` has become a subclass of ``Rotating``, and the distortion effect in ``Transform`` will not appear
- Removed ``MoveCar`` animation
- Added ``TransformMatchingShapes(mobject, target_mobject)`` and ``TransformMatchingTex(mobject, target_mobject)``
- ``Camera``
- Removed all camera classes except ``Camera`` (``MappingCamera``, ``MovingCamera``, ``MultiCamera``) and all functions in ``ThreeDCamera``
- Implemented ``CameraFrame`` (as a ``Mobject``)
- Can be called by ``self.camera.frame`` in ``Scene``
- All methods of ``Mobject`` can be used, such as ``.shift()``, ``.scale()``, etc.
- Call ``.to_default_state()`` to place in the default position
- Set the Euler angles of the camera by ``.set_euler_angles(theta, phi, gamma)``
- Set three single Euler angles by ``.set_theta(theta)``, ``.set_phi(phi)``, ``.set_gamma(gamma)``
- Use ``.increment_theta(dtheta)``, ``.increment_phi(dphi)``, ``.increment_gamma(gamma)`` to increase the three Euler angles by a certain value. Can be used to realize automatic rotation ``self.camera.frame.add_updater(lambda mob, dt: mob.increment_theta(0.1 * dt))``
- ``Camera`` adds a light source, which is a ``Point``, which can be called by ``self.camera.light_source`` in ``Scene`` to move and so on. The default position is ``(- 10, 10, 10)``
- Delete ``Container``
- ``Mobject``
- ``svg`` related
- Added ``Checkmark`` and ``Exmark``
- Some unnecessary classes have been removed from ``drawings.py``
- Removed ``Code`` and ``Paragraph`` (by mistake)
- ``TexMobject`` is renamed to ``Tex``, ``TextMobject`` is renamed to ``TexText``
- ``font_size`` has been added to ``Tex``, ``TexText`` and ``Text``
- ``Tex`` and ``TexText`` added ``isolate``, which is a list, which will be automatically split
- Mobject ``types``
- Added a new class ``Surface``, which is the parent class of ``ParametricSurface`` and ``TexturedSurface``.
- Added the group ``SGroup`` for ``Surface``
- Added ``TexturedSurface(uv_surface, image_file, dark_image_file=None)``, where ``uv_surface`` is a ``Surface``, ``image_file`` is the image to be posted, and ``dark_image_file`` is the image to be posted in the dark (default and ``image_file`` is the same)
- Deleted ``Mobject1D``, ``Mobject2D``, ``PointCloudDot``
- Added ``DotCloud`` (a ``PMobject``), which has been greatly optimized
- Removed ``AbstractImageMobject``, ``ImageMobjectFromCamera``
- Removed ``sheen`` from ``VMobject``
- ``Mobject``
- Added ``gloss`` and ``shadow``, which are the numbers between ``[0, 1]`` respectively. There are four methods of ``.get_gloss()``, ``.set_gloss(gloss)``, ``.get_shadow()``, ``.set_shadow(shadow)``
- Added ``.get_grid(n_rows, n_cols)`` to copy into grid
- Added ``.set_color_by_code(glsl_code)`` to use GLSL code to change the color
- Added ``.set_color_by_xyz_func(glsl_snippet, min_value=-5.0, max_value=5.0, colormap="viridis")`` to pass in GLSL expression in the form of ``x,y,z``, the return value should be a floating point number
- Coordinate system (including ``Axes``, ``ThreeDAxes``, ``NumberPlane``, ``ComplexPlane``)
- No longer use ``x_min``, ``x_max``, ``y_min``, ``y_max``, but use ``x_range``, ``y_range`` as a ``np.array()``, containing three numbers ``np.array([ Minimum, maximum, step size])``
- Added the abbreviation ``.i2gp(x, graph)`` of ``.input_to_graph_point(x, graph)``
- Added some functions of the original ``GraphScene``
- Added ``.get_v_line(point)``, ``.get_h_line(point)`` to return the line from ``point`` to the two coordinate axes, and specify the line type through the keyword argument of ``line_func`` (default ``DashedLine``)
- Added ``.get_graph_label(graph, label, x, direction, buff, color)`` to return the label added to the image
- Added ``.get_v_line_to_graph(x, graph)``, ``.get_h_line_to_graph(x, graph)`` to return the line from the point with the abscissa of ``x`` on the ``graph`` to the two- axis line
- Added ``.angle_of_tangent(x, graph, dx=EPSILON)``, returns the inclination angle of ``graph`` at ``x``
- Added ``.slope_of_tangent(x, graph, dx=EPSILON)``, returns the slope of tangent line of ``graph`` at ``x``
- Added ``.get_tangent_line(x, graph, length=5)`` to return the tangent line of ``graph`` at ``x``
- Added ``.get_riemann_rectangles(graph, x_range, dx, input_sample_type, ...)`` to return Riemann rectangles (a ``VGroup``)
- The attribute ``number_line_config`` of ``Axes`` is renamed to ``axis_config``
- ``Axes`` original ``.get_coordinate_labels(x_values, y_values)`` method was renamed to ``.add_coordinate_labels(x_values, y_values)`` (but it is not added to the screen)
- ``.add_coordinate_labels(numbers)`` of ``ComplexPlane`` will directly add the coordinates to the screen
- ``NumberLine``
- No longer use ``x_min``, ``x_max``, ``tick_frequency``, but use ``x_range``, which is an array containing three numbers ``[min, max, step]``
- The original ``label_direction`` attribute changed to the ``line_to_number_direction`` attribute
- Replace ``tip_width`` and ``tip_height`` with ``tip_config`` (dictionary) attributes
- The original ``exclude_zero_from_default`` attribute is modified to the ``numbers_to_exclude`` attribute (default is None)
- The original ``.add_tick_marks()`` method was changed to the ``.add_ticks()`` method
- Delete the ``.get_number_mobjects(*numbers)`` method, only use the ``.add_numbers(x_values=None, excluding=None)`` method
- Three-dimensional objects
- Added ``SurfaceMesh(uv_surface)``, pass in a ``Surface`` to generate its uv mesh
- ``ParametricSurface`` no longer uses ``u_min, u_max, v_min, v_max``, but instead uses ``u_range, v_range``, which is a tuple (``(min, max)``), and ``resolution`` can be set larger, dont worry Speed issue
- Added ``Torus``, controlled by ``r1, r2`` keyword parameters
- Added ``Cylinder``, controlled by ``height, radius`` keyword parameters
- Added ``Line3D`` (extremely thin cylinder), controlled by the ``width`` keyword parameter
- Added ``Disk3D``, controlled by ``radius`` keyword parameter
- Add ``Square3D``, controlled by ``side_length`` keyword parameter
- Improved ``Cube`` and ``Prism``, the usage remains unchanged
- Other objects
- ``ParametricFunction`` is renamed to ``ParametricCurve``. Instead of using ``t_min, t_max, step_size``, use ``t_range``, which is an array of three numbers (``[t_min, t_max, step_size]``). ``dt`` was renamed to ``epsilon``. Other usage remains unchanged
- All ``TipableVMobject`` can pass in ``tip_length`` to control the style of ``tip``
- ``Line`` adds ``.set_points_by_ends(start, end, buff=0, path_arc=0)`` method
- ``Line`` added ``.get_projection(point)`` to return the projection position of ``point`` on a straight line
- ``Arrow`` adds three attributes of ``thickness, tip_width_ratio, tip_angle``
- ``CubicBezier`` is changed to ``a0, h0, h1, a1``, that is, only a third-order Bezier curve is supported
- ``Square`` can be initialized directly by passing in ``side_length`` instead of using the keyword ``side_length=``
- ``always_redraw(func, *args, **kwargs)`` supports incoming parameters ``*args, **kwargs``
- The ``digit_to_digit_buff`` property of ``DecimalNumber`` has been renamed to ``digit_buff_per_font_unit``, and the ``.scale()`` method has been improved
- ``ValueTracker`` adds ``value_type`` attribute, the default is ``np.float64``
- ``Scene``
- Removed all functions of ``GraphScene`` (moved to ``once_useful_constructs``), ``MovingCameraScene``, ``ReconfigurableScene``, ``SceneFromVideo``, ``ZoomedScene``, and ``ThreeDScene``. Because these can basically be achieved by adjusting ``CameraFrame`` (``self.camera.frame``)
- Currently ``SampleSpaceScene`` and ``VectorScene`` have not been changed for the new version, so it is not recommended to use (only ``Scene`` is recommended)
- Fix the export of gif, just use the ``-i`` option directly
- Added the ``.interact()`` method, during which the mouse and keyboard can be used to continue the interaction, which will be executed by default after the scene ends
- Added ``.embed()`` method, open iPython terminal to enter interactive mode
- Added ``.save_state()`` method to save the current state of the scene
- Added ``.restore()`` method to restore the entire scene to the saved state
- ``utils``
- A series of functions related to second-order Bezier have been added to ``utils/bezier.py``
- Added a function to read color map from ``matplotlib`` in ``utils/color.py``
- Added a series of related functions for processing folders/custom styles/object families
- ``resize_array``, ``resize_preserving_order``, ``resize_with_interpolation`` three functions have been added to ``utils/iterables.py``
- The definition of ``smooth`` is updated in ``utils/rate_functions.py``
- ``clip(a, min_a, max_a)`` function has been added to ``utils/simple_functions.py``
- Some functions have been improved in ``utils/space_ops.py``, some functions for space calculation, and functions for processing triangulation have been added
- ``constants``
- Fixed the aspect ratio of the screen to 16:9
- Deleted the old gray series (``LIGHT_GREY``, ``GREY``, ``DARK_GREY``, ``DARKER_GREY``), added a new series of gray ``GREY_A`` ~ ``GREY_E``

View file

@ -18,6 +18,7 @@ And here is a Chinese version of this documentation: https://manim.ml/shaders
getting_started/example_scenes
getting_started/config
getting_started/structure
getting_started/whatsnew
.. toctree::
:maxdepth: 2

View file

@ -331,6 +331,85 @@ class UpdatersExample(Scene):
self.wait(4 * PI)
class CoordinateSystemExample(Scene):
def construct(self):
axes = Axes(
# x-axis ranges from -1 to 10, with a default step size of 1
x_range=(-1, 10),
# y-axis ranges from -2 to 10 with a step size of 0.5
y_range=(-2, 2, 0.5),
# The axes will be stretched so as to match the specified
# height and width
height=6,
width=10,
# Axes is made of two NumberLine mobjects. You can specify
# their configuration with axis_config
axis_config={
"stroke_color": GREY_A,
"stroke_width": 2,
},
# Alternatively, you can specify configuration for just one
# of them, like this.
y_axis_config={
"include_tip": False,
}
)
# Keyword arguments of add_coordinate_labels can be used to
# configure the DecimalNumber mobjects which it creates and
# adds to the axes
axes.add_coordinate_labels(
font_size=20,
num_decimal_places=1,
)
self.add(axes)
# Axes descends from the CoordinateSystem class, meaning
# you can call call axes.coords_to_point, abbreviated to
# axes.c2p, to associate a set of coordinates with a point,
# like so:
dot = Dot(color=RED)
dot.move_to(axes.c2p(0, 0))
self.play(FadeIn(dot, scale=0.5))
self.play(dot.animate.move_to(axes.c2p(3, 2)))
self.wait()
self.play(dot.animate.move_to(axes.c2p(5, 0.5)))
self.wait()
# Similarly, you can call axes.point_to_coords, or axes.p2c
# print(axes.p2c(dot.get_center()))
# We can draw lines from the axes to better mark the coordinates
# of a given point.
# Here, the always_redraw command means that on each new frame
# the lines will be redrawn
h_line = always_redraw(lambda: axes.get_h_line(dot.get_left()))
v_line = always_redraw(lambda: axes.get_v_line(dot.get_bottom()))
self.play(
ShowCreation(h_line),
ShowCreation(v_line),
)
self.play(dot.animate.move_to(axes.c2p(3, -2)))
self.wait()
self.play(dot.animate.move_to(axes.c2p(1, 1)))
self.wait()
# If we tie the dot to a particular set of coordinates, notice
# that as we move the axes around it respects the coordinate
# system defined by them.
f_always(dot.move_to, lambda: axes.c2p(1, 1))
self.play(
axes.animate.scale(0.75),
axes.animate.to_corner(UL),
run_time=2,
)
self.wait()
self.play(FadeOut(VGroup(axes, dot, h_line, v_line)))
# Other coordinate systems you can play around with include
# ThreeDAxes, NumberPlane, and ComplexPlane.
class GraphExample(Scene):
def construct(self):
axes = Axes((-3, 10), (-1, 8))
@ -412,85 +491,6 @@ class GraphExample(Scene):
self.wait()
class CoordinateSystemExample(Scene):
def construct(self):
axes = Axes(
# x-axis ranges from -1 to 10, with a default step size of 1
x_range=(-1, 10),
# y-axis ranges from -2 to 10 with a step size of 0.5
y_range=(-2, 2, 0.5),
# The axes will be stretched so as to match the specified
# height and width
height=6,
width=10,
# Axes is made of two NumberLine mobjects. You can specify
# their configuration with axis_config
axis_config={
"stroke_color": GREY_A,
"stroke_width": 2,
},
# Alternatively, you can specify configuration for just one
# of them, like this.
y_axis_config={
"include_tip": False,
}
)
# Keyword arguments of add_coordinate_labels can be used to
# configure the DecimalNumber mobjects which it creates and
# adds to the axes
axes.add_coordinate_labels(
font_size=20,
num_decimal_places=1,
)
self.add(axes)
# Axes descends from the CoordinateSystem class, meaning
# you can call call axes.coords_to_point, abbreviated to
# axes.c2p, to associate a set of coordinates with a point,
# like so:
dot = Dot(color=RED)
dot.move_to(axes.c2p(0, 0))
self.play(FadeIn(dot, scale=0.5))
self.play(dot.animate.move_to(axes.c2p(3, 2)))
self.wait()
self.play(dot.animate.move_to(axes.c2p(5, 0.5)))
self.wait()
# Similarly, you can call axes.point_to_coords, or axes.p2c
# print(axes.p2c(dot.get_center()))
# We can draw lines from the axes to better mark the coordinates
# of a given point.
# Here, the always_redraw command means that on each new frame
# the lines will be redrawn
h_line = always_redraw(lambda: axes.get_h_line(dot.get_left()))
v_line = always_redraw(lambda: axes.get_v_line(dot.get_bottom()))
self.play(
ShowCreation(h_line),
ShowCreation(v_line),
)
self.play(dot.animate.move_to(axes.c2p(3, -2)))
self.wait()
self.play(dot.animate.move_to(axes.c2p(1, 1)))
self.wait()
# If we tie the dot to a particular set of coordinates, notice
# that as we move the axes around it respects the coordinate
# system defined by them.
f_always(dot.move_to, lambda: axes.c2p(1, 1))
self.play(
axes.animate.scale(0.75),
axes.animate.to_corner(UL),
run_time=2,
)
self.wait()
self.play(FadeOut(VGroup(axes, dot, h_line, v_line)))
# Other coordinate systems you can play around with include
# ThreeDAxes, NumberPlane, and ComplexPlane.
class SurfaceExample(Scene):
CONFIG = {
"camera_class": ThreeDCamera,

View file

@ -25,8 +25,8 @@ class CoordinateSystem():
"""
CONFIG = {
"dimension": 2,
"x_range": np.array([-8, 8, 1]),
"y_range": np.array([-4, 4, 1]),
"x_range": np.array([-8, 8, 1.0]),
"y_range": np.array([-4, 4, 1.0]),
"width": None,
"height": None,
"num_sampled_graph_points_per_tick": 5,
@ -280,7 +280,7 @@ class Axes(VGroup, CoordinateSystem):
if x_range is not None:
self.x_range[:len(x_range)] = x_range
if y_range is not None:
self.y_range[:len(x_range)] = y_range
self.y_range[:len(y_range)] = y_range
self.x_axis = self.create_axis(
self.x_range, self.x_axis_config, self.width,