diff --git a/docs/source/api/axis.rst b/docs/source/api/axis.rst index 3213a82a9..2be0d5174 100644 --- a/docs/source/api/axis.rst +++ b/docs/source/api/axis.rst @@ -3,7 +3,7 @@ Axis and Grid -------------- -.. currentmodule:: chaco.api +.. currentmodule:: chaco.axis :class:`PlotAxis` ========================== @@ -11,18 +11,29 @@ Axis and Grid :members: :show-inheritance: +:class:`MinorPlotAxis` +========================== +.. autoclass:: MinorPlotAxis + :members: + :show-inheritance: +.. currentmodule:: chaco.label_axis + :class:`LabelAxis` ========================== .. autoclass:: LabelAxis :members: :show-inheritance: +.. currentmodule:: chaco.grid + :class:`PlotGrid` ========================== .. autoclass:: PlotGrid :members: :show-inheritance: +.. currentmodule:: chaco.ticks + :class:`AbstractTickGenerator` =============================== .. autoclass:: AbstractTickGenerator diff --git a/docs/source/api/containers.rst b/docs/source/api/containers.rst index 18fd90a61..ec6fe2a97 100644 --- a/docs/source/api/containers.rst +++ b/docs/source/api/containers.rst @@ -4,7 +4,7 @@ Containers ---------- -.. currentmodule:: chaco.api +.. currentmodule:: chaco.base_plot_container :class:`BasePlotContainer` ========================== @@ -12,6 +12,8 @@ Containers :members: :show-inheritance: +.. currentmodule:: chaco.plot_containers + :class:`OverlayPlotContainer` ============================= .. autoclass:: OverlayPlotContainer @@ -35,3 +37,17 @@ Containers .. autoclass:: GridPlotContainer :members: :show-inheritance: + +:class:`StackedPlotContainer` +============================= +.. autoclass:: StackedPlotContainer + :members: + :show-inheritance: + +.. currentmodule:: chaco.selectable_overlay_container + +:class:`SelectableOverlayPlotContainer` +======================================= +.. autoclass:: SelectableOverlayPlotContainer + :members: + :show-inheritance: diff --git a/docs/source/api/data_ranges.rst b/docs/source/api/data_ranges.rst index 8b1527a0b..bbb6e0aff 100644 --- a/docs/source/api/data_ranges.rst +++ b/docs/source/api/data_ranges.rst @@ -1,10 +1,10 @@ -.. _data_ranges: +.. _data_ranges_api: Data Ranges ----------- -.. currentmodule:: chaco.api +.. currentmodule:: chaco.abstract_data_range :class:`AbstractDataRange` ========================== @@ -12,18 +12,24 @@ Data Ranges :members: :show-inheritance: +.. currentmodule:: chaco.base_data_range + :class:`BaseDataRange` ====================== .. autoclass:: BaseDataRange :members: :show-inheritance: +.. currentmodule:: chaco.data_range_1d + :class:`DataRange1D` ==================== .. autoclass:: DataRange1D :members: :show-inheritance: +.. currentmodule:: chaco.data_range_2d + :class:`DataRange2D` ==================== .. autoclass:: DataRange2D diff --git a/docs/source/api/data_sources.rst b/docs/source/api/data_sources.rst index edfb16c5f..133a5b0e8 100644 --- a/docs/source/api/data_sources.rst +++ b/docs/source/api/data_sources.rst @@ -1,10 +1,10 @@ -.. _data_sources: +.. _data_sources_api: Data Sources ------------ -.. currentmodule:: chaco.api +.. currentmodule:: chaco.abstract_data_source :class:`AbstractDataSource` =========================== @@ -12,30 +12,40 @@ Data Sources :members: :show-inheritance: +.. currentmodule:: chaco.array_data_source + :class:`ArrayDataSource` ======================== .. autoclass:: ArrayDataSource :members: :show-inheritance: +.. currentmodule:: chaco.multi_array_data_source + :class:`MultiArrayDataSource` ============================= .. autoclass:: MultiArrayDataSource :members: :show-inheritance: +.. currentmodule:: chaco.point_data_source + :class:`PointDataSource` ======================== .. autoclass:: PointDataSource :members: :show-inheritance: +.. currentmodule:: chaco.grid_data_source + :class:`GridDataSource` ======================= .. autoclass:: GridDataSource :members: :show-inheritance: +.. currentmodule:: chaco.image_data + :class:`ImageData` ================== .. autoclass:: ImageData diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst new file mode 100644 index 000000000..ca8770911 --- /dev/null +++ b/docs/source/api/index.rst @@ -0,0 +1,24 @@ +:orphan: + +.. _api_reference: + +============= +API Reference +============= + +This guide provides in-depth API documentation for the main classes and +objects in the Chaco package. + +.. toctree:: + :maxdepth: 2 + + visual_components.rst + containers.rst + data_sources.rst + mappers.rst + data_ranges.rst + renderers.rst + plot_factories.rst + tools.rst + axis.rst + diff --git a/docs/source/api/mappers.rst b/docs/source/api/mappers.rst index 191493e47..c04780526 100644 --- a/docs/source/api/mappers.rst +++ b/docs/source/api/mappers.rst @@ -4,7 +4,7 @@ Mappers ------- -.. currentmodule:: chaco.api +.. currentmodule:: chaco.abstract_mapper :class:`AbstractMapper` ======================= @@ -12,45 +12,58 @@ Mappers :members: :show-inheritance: +.. currentmodule:: chaco.base_1d_mapper + :class:`Base1DMapper` ===================== .. autoclass:: Base1DMapper :members: :show-inheritance: +.. currentmodule:: chaco.linear_mapper + :class:`LinearMapper` ===================== .. autoclass:: LinearMapper :members: :show-inheritance: +.. currentmodule:: chaco.log_mapper + :class:`LogMapper` ================== .. autoclass:: LogMapper :members: :show-inheritance: +.. currentmodule:: chaco.grid_mapper + :class:`GridMapper` =================== .. autoclass:: GridMapper :members: :show-inheritance: +.. currentmodule:: chaco.color_mapper + :class:`ColorMapper` ==================== .. autoclass:: ColorMapper :members: :show-inheritance: +.. currentmodule:: chaco.color_mapper + :class:`ColorMapTemplate` ========================= .. autoclass:: ColorMapTemplate :members: :show-inheritance: +.. currentmodule:: chaco.transform_color_mapper + :class:`TransformColorMapper` ============================= .. autoclass:: TransformColorMapper :members: - :show-inheritance: - + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/plot_factories.rst b/docs/source/api/plot_factories.rst index 927a3fce7..815740e07 100644 --- a/docs/source/api/plot_factories.rst +++ b/docs/source/api/plot_factories.rst @@ -3,7 +3,7 @@ Plot Factories -------------- -.. currentmodule:: chaco.api +.. currentmodule:: chaco.plot_factory `create_bar_plot` ================= @@ -30,24 +30,32 @@ Plot Factories .. autofunction:: add_default_grids +.. currentmodule:: chaco.abstract_plot_data + :class:`AbstractPlotData` ========================= .. autoclass:: AbstractPlotData :members: :show-inheritance: +.. currentmodule:: chaco.array_plot_data + :class:`ArrayPlotData` ====================== .. autoclass:: ArrayPlotData :members: :show-inheritance: +.. currentmodule:: chaco.plot + :class:`Plot` ============= .. autoclass:: Plot :members: :show-inheritance: +.. currentmodule:: chaco.toolbar_plot + :class:`ToolbarPlot` ==================== .. autoclass:: ToolbarPlot diff --git a/docs/source/api/renderers.rst b/docs/source/api/renderers.rst index 5316a1b5a..e9360019c 100644 --- a/docs/source/api/renderers.rst +++ b/docs/source/api/renderers.rst @@ -4,7 +4,7 @@ Renderers ---------- -.. currentmodule:: chaco.api +.. currentmodule:: chaco.barplot :class:`BarPlot` ================ @@ -12,125 +12,183 @@ Renderers :members: :show-inheritance: +.. currentmodule:: chaco.base_1d_plot + :class:`Base1DPlot` =================== .. autoclass:: Base1DPlot :members: :show-inheritance: +.. currentmodule:: chaco.base_2d_plot + :class:`Base2DPlot` =================== .. autoclass:: Base2DPlot :members: :show-inheritance: +.. currentmodule:: chaco.base_xy_plot + :class:`BaseXYPlot` =================== .. autoclass:: BaseXYPlot :members: :show-inheritance: +.. currentmodule:: chaco.scatterplot + :class:`ScatterPlot` ==================== .. autoclass:: ScatterPlot :members: :show-inheritance: +.. currentmodule:: chaco.image_plot + :class:`ImagePlot` ================== .. autoclass:: ImagePlot :members: :show-inheritance: +.. currentmodule:: chaco.cmap_image_plot + :class:`CMapImagePlot` ====================== .. autoclass:: CMapImagePlot :members: :show-inheritance: +.. currentmodule:: chaco.contour_line_plot + :class:`ContourLinePlot` ======================== .. autoclass:: ContourLinePlot :members: :show-inheritance: +.. currentmodule:: chaco.lineplot + :class:`LinePlot` ======================== .. autoclass:: LinePlot :members: :show-inheritance: +.. currentmodule:: chaco.colormapped_scatterplot + :class:`ColormappedScatterPlot` =============================== .. autoclass:: ColormappedScatterPlot :members: :show-inheritance: +.. currentmodule:: chaco.colormapped_selection_overlay + :class:`ColormappedSelectionOverlay` ==================================== .. autoclass:: ColormappedSelectionOverlay :members: :show-inheritance: +.. currentmodule:: chaco.polygon_plot + :class:`PolygonPlot` ==================== .. autoclass:: PolygonPlot :members: :show-inheritance: +.. currentmodule:: chaco.errorbar_plot + :class:`ErrorBarPlot` ===================== .. autoclass:: ErrorBarPlot :members: :show-inheritance: +.. currentmodule:: chaco.filled_line_plot + :class:`FilledLinePlot` ======================= .. autoclass:: FilledLinePlot :members: :show-inheritance: +.. currentmodule:: chaco.quiverplot + :class:`QuiverPlot` =================== .. autoclass:: QuiverPlot :members: :show-inheritance: +.. currentmodule:: chaco.candle_plot + :class:`CandlePlot` =================== .. autoclass:: CandlePlot :members: :show-inheritance: +.. currentmodule:: chaco.segment_plot + +:class:`SegmentPlot` +==================== +.. autoclass:: SegmentPlot + :members: + :show-inheritance: + +.. currentmodule:: chaco.text_plot + +:class:`TextPlot` +================= +.. autoclass:: TextPlot + :members: + :show-inheritance: + +.. currentmodule:: chaco.multi_line_plot + :class:`MultiLinePlot` ====================== .. autoclass:: MultiLinePlot :members: :show-inheritance: +.. currentmodule:: chaco.scatterplot_1d + :class:`ScatterPlot1D` ====================== -.. autoclass:: ScatterPlot +.. autoclass:: ScatterPlot1D + :members: + :show-inheritance: + +.. currentmodule:: chaco.jitterplot + +:class:`JitterPlot` +===================== +.. autoclass:: JitterPlot + :members: + :show-inheritance: + +.. currentmodule:: chaco.line_scatterplot_1d + +:class:`LineScatterPlot1D` +============================ +.. autoclass:: LineScatterPlot1D :members: :show-inheritance: -..:class:`JitterPlot` -..=================== -.... autoclass:: JitterPlot -.. :members: -.. :show-inheritance: +.. currentmodule:: chaco.text_plot_1d -..:class:`LineScatterPlot1D` -..=================== -.... autoclass:: LineScatterPlot1D -.. :members: -.. :show-inheritance: +:class:`TextPlot1D` +===================== +.. autoclass:: TextPlot1D + :members: + :show-inheritance: -..:class:`TextPlot1D` -..=================== -.... autoclass:: TextPlot1D -.. :members: -.. :show-inheritance: +.. currentmodule:: chaco.variable_size_scatterplot :class:`VariableSizeScatterPlot` ================================ @@ -138,6 +196,8 @@ Renderers :members: :show-inheritance: +.. currentmodule:: chaco.horizon_plot + :class:`HorizonPlot` ==================== .. autoclass:: HorizonPlot diff --git a/docs/source/api/tools.rst b/docs/source/api/tools.rst index af528287d..32dd526c4 100644 --- a/docs/source/api/tools.rst +++ b/docs/source/api/tools.rst @@ -3,7 +3,7 @@ Tools ------ -.. currentmodule:: chaco.tools.api +.. currentmodule:: chaco.tools.better_zoom :class:`BetterZoom` ========================== @@ -11,54 +11,72 @@ Tools :members: :show-inheritance: +.. currentmodule:: chaco.tools.better_selecting_zoom + :class:`BetterSelectingZoom` ============================ .. autoclass:: BetterSelectingZoom :members: :show-inheritance: +.. currentmodule:: chaco.tools.broadcaster + :class:`BroadcasterTool` ========================== .. autoclass:: BroadcasterTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.dataprinter + :class:`DataPrinter` ========================== .. autoclass:: DataPrinter :members: :show-inheritance: +.. currentmodule:: chaco.tools.data_label_tool + :class:`DataLabelTool` ========================== .. autoclass:: DataLabelTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.drag_tool + :class:`DragTool` ========================== .. autoclass:: DragTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.draw_points_tool + :class:`DrawPointsTool` ========================== .. autoclass:: DrawPointsTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.drag_zoom + :class:`DragZoom` ========================== .. autoclass:: DragZoom :members: :show-inheritance: +.. currentmodule:: chaco.tools.highlight_tool + :class:`HighlightTool` ========================== .. autoclass:: HighlightTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.image_inspector_tool + :class:`ImageInspectorTool` =========================== .. autoclass:: ImageInspectorTool @@ -71,72 +89,96 @@ Tools :members: :show-inheritance: +.. currentmodule:: chaco.tools.lasso_selection + :class:`LassoSelection` ========================== .. autoclass:: LassoSelection :members: :show-inheritance: +.. currentmodule:: chaco.tools.legend_tool + :class:`LegendTool` ========================== .. autoclass:: LegendTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.legend_highlighter + :class:`LegendHighlighter` ========================== .. autoclass:: LegendHighlighter :members: :show-inheritance: +.. currentmodule:: chaco.tools.line_inspector + :class:`LineInspector` ========================== .. autoclass:: LineInspector :members: :show-inheritance: +.. currentmodule:: chaco.tools.line_segment_tool + :class:`LineSegmentTool` ========================== .. autoclass:: LineSegmentTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.move_tool + :class:`MoveTool` ========================== .. autoclass:: MoveTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.pan_tool + :class:`PanTool` ========================== .. autoclass:: PanTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.point_marker + :class:`PointMarker` ========================== .. autoclass:: PointMarker :members: :show-inheritance: +.. currentmodule:: chaco.tools.range_selection + :class:`RangeSelection` ========================== .. autoclass:: RangeSelection :members: :show-inheritance: +.. currentmodule:: chaco.tools.range_selection_2d + :class:`RangeSelection2D` ========================== .. autoclass:: RangeSelection2D :members: :show-inheritance: +.. currentmodule:: chaco.tools.range_selection_overlay + :class:`RangeSelectionOverlay` ============================== .. autoclass:: RangeSelectionOverlay :members: :show-inheritance: +.. currentmodule:: chaco.tools.regression_lasso + :class:`RegressionLasso` ========================== .. autoclass:: RegressionLasso @@ -149,30 +191,40 @@ Tools :members: :show-inheritance: +.. currentmodule:: chaco.tools.save_tool + :class:`SaveTool` ========================== .. autoclass:: SaveTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.scatter_inspector + :class:`ScatterInspector` ========================== .. autoclass:: ScatterInspector :members: :show-inheritance: +.. currentmodule:: chaco.tools.select_tool + :class:`SelectTool` ========================== .. autoclass:: SelectTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.simple_inspector + :class:`SimpleInspectorTool` ============================ .. autoclass:: SimpleInspectorTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.tool_states + :class:`ZoomState` ========================== .. autoclass:: ZoomState @@ -197,28 +249,58 @@ Tools :members: :show-inheritance: +.. currentmodule:: chaco.tools.tracking_pan_tool + :class:`TrackingPanTool` ========================== .. autoclass:: TrackingPanTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.tracking_zoom + :class:`TrackingZoom` ========================== .. autoclass:: TrackingZoom :members: :show-inheritance: +.. currentmodule:: chaco.tools.traits_tool + :class:`TraitsTool` ========================== .. autoclass:: TraitsTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.zoom_tool + :class:`ZoomTool` ========================== .. autoclass:: ZoomTool :members: :show-inheritance: +.. currentmodule:: chaco.tools.cursor_tool + +:class:`BaseCursorTool` +========================== +.. autoclass:: BaseCursorTool + :members: + :show-inheritance: + +`CursorTool` +============ +.. autofunction:: CursorTool + +:class:`CursorTool1D` +========================== +.. autoclass:: CursorTool1D + :members: + :show-inheritance: +:class:`CursorTool2D` +========================== +.. autoclass:: CursorTool2D + :members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/visual_components.rst b/docs/source/api/visual_components.rst index 5396bedd6..5226b03ba 100644 --- a/docs/source/api/visual_components.rst +++ b/docs/source/api/visual_components.rst @@ -3,7 +3,7 @@ Visual Components ----------------- -.. currentmodule:: chaco.api +.. currentmodule:: chaco.abstract_plot_renderer :class:`AbstractPlotRenderer` ============================= @@ -11,65 +11,95 @@ Visual Components :members: :show-inheritance: +.. currentmodule:: chaco.abstract_overlay + :class:`AbstractOverlay` ======================== .. autoclass:: AbstractOverlay :members: :show-inheritance: +.. currentmodule:: chaco.base_plot_frame + :class:`BasePlotFrame` ====================== .. autoclass:: BasePlotFrame :members: :show-inheritance: +.. currentmodule:: chaco.cross_plot_frame + :class:`CrossPlotFrame` ======================= .. autoclass:: CrossPlotFrame :members: :show-inheritance: +.. currentmodule:: chaco.data_view + :class:`DataView` ================= .. autoclass:: DataView :members: :show-inheritance: +.. currentmodule:: chaco.simple_plot_frame + :class:`SimplePlotFrame` ======================== .. autoclass:: SimplePlotFrame :members: :show-inheritance: +.. currentmodule:: chaco.plot_component + :class:`PlotComponent` ====================== .. autoclass:: PlotComponent :members: :show-inheritance: +.. currentmodule:: chaco.plot_graphics_context + :class:`PlotGraphicsContext` ============================ .. autoclass:: PlotGraphicsContext :members: :show-inheritance: +.. currentmodule:: chaco.label + :class:`Label` ============== .. autoclass:: Label :members: :show-inheritance: +.. currentmodule:: chaco.plot_label + :class:`PlotLabel` ================== .. autoclass:: PlotLabel :members: :show-inheritance: +.. currentmodule:: chaco.legend + :class:`Legend` =============== .. autoclass:: Legend :members: :show-inheritance: + +.. currentmodule:: chaco.selectable_legend + +:class:`SelectableLegend` +========================= +.. autoclass:: SelectableLegend + :members: + :show-inheritance: + +.. currentmodule:: chaco.tooltip :class:`ToolTip` ================ @@ -77,30 +107,40 @@ Visual Components :members: :show-inheritance: +.. currentmodule:: chaco.data_label + :class:`DataLabel` ================== .. autoclass:: DataLabel :members: :show-inheritance: +.. currentmodule:: chaco.lasso_overlay + :class:`LassoOverlay` ===================== .. autoclass:: LassoOverlay :members: :show-inheritance: +.. currentmodule:: chaco.color_bar + :class:`ColorBar` ================= .. autoclass:: ColorBar :members: :show-inheritance: +.. currentmodule:: chaco.text_box_overlay + :class:`TextBoxOverlay` ======================= .. autoclass:: TextBoxOverlay :members: :show-inheritance: +.. currentmodule:: chaco.scatter_inspector_overlay + :class:`ScatterInspectorOverlay` ================================ .. autoclass:: ScatterInspectorOverlay diff --git a/docs/source/architecture_overview.rst b/docs/source/developer_reference/architecture_overview.rst similarity index 87% rename from docs/source/architecture_overview.rst rename to docs/source/developer_reference/architecture_overview.rst index 391104e10..17d0c6c45 100644 --- a/docs/source/architecture_overview.rst +++ b/docs/source/developer_reference/architecture_overview.rst @@ -1,3 +1,6 @@ +.. _architecture: + + ********************* Architecture Overview ********************* @@ -8,43 +11,6 @@ Architecture Overview .. contents:: - - -Core Ideas -========== - -The Chaco toolkit is defined by a few core architectural ideas: - -* **Plots are compositions of visual components** - - Everything you see in a plot is some sort of graphical widget, - with position, shape, and appearance attributes, and with an - opportunity to respond to events. - -* **Separation between data and screen space** - - Although everything in a plot eventually ends up rendering into a common - visual area, there are aspects of the plot which are intrinsically - screen-space, and some which are fundamentally data-space. Preserving - the distinction between these two domains allows us to think about - visualizations in a structured way. - -* **Modular design and extensible classes** - - Chaco is meant to be used for writing tools and applications, and code - reuse and good class design are important. We use the math behind the - data and visualizations to give us architectural direction and conceptual - modularity. The Traits framework allows us to use events to couple - disjoint components at another level of modularity. - - Also, rather than building super-flexible core objects with myriad - configuration attributes, Chaco's classes are written with subclassing in - mind. While they are certainly configurable, the classes themselves are - written in a modular way so that subclasses can easily customize - particular aspects of a visual component's appearance or a tool's - behavior. - - .. _chaco_enable_kiva: The Relationship Between Chaco, Enable, and Kiva @@ -182,6 +148,18 @@ Chaco classes, and illustrates some sample usages. For a more detailed list of the class hierarchy, please see :ref:`modules_and_classes`. +Chaco is meant to be used for writing tools and applications, and code reuse +and good class design are important. We use the math behind the data and +visualizations to give us architectural direction and conceptual modularity. +The Traits framework allows us to use events to couple disjoint components at +another level of modularity. + +Also, rather than building super-flexible core objects with myriad +configuration attributes, Chaco's classes are written with subclassing in mind. +While they are certainly configurable, the classes themselves are written in a +modular way so that subclasses can easily customize particular aspects of a +visual component's appearance or a tool's behavior. + At the highest level, Chaco consists of: * Visual components that render to screen or an output device @@ -224,8 +202,3 @@ vertical grids. These other visuals are embodied as separate, distinct components: axes are drawn by the :class:`PlotAxis` component, and grids are drawn by the :class:`PlotGrid` component. Both of these overlays require a mapper in order to know where on the screen they should draw. - -.. So, the pipeline looks like: - - - diff --git a/docs/source/developer_reference/fundamentals.rst b/docs/source/developer_reference/fundamentals.rst new file mode 100644 index 000000000..32d4fe67e --- /dev/null +++ b/docs/source/developer_reference/fundamentals.rst @@ -0,0 +1,760 @@ +.. _fundamentals: + +================== +Chaco Fundamentals +================== + +While you can go a long way using the high-level APIs provided by the +:py:class:`~chaco.plot.Plot` class, to use Chaco to its full potential +it helps to have a deeper understanding of the building blocks of the +library. + +Foundations +=========== + +Chaco relies on a number of underlying libraries for core capabilities. +Understanding these libraries is important for writing heavily interactive +visualizations, as well as new tools, overlays and plot renderers. + +Traits +------ + +Chaco is written using `Traits `_ which not +only provides basic type-checking of data, but also attribute change +notification which is key to the interactive updating of Chaco. + +You should be comfortable with Traits when writing any significant +Chaco-based application or when extending Chaco's capabilities. + +TraitsUI +-------- + +`TraitsUI `_ is a rapid GUI application +development library built on top of Traits. While it is not required for +the development of applications that use Chaco, it is the most natural way +of providing other UI elements for your users to interact with your +visualizations; or alternatively the most natural environment for writing +applications which embed Chaco plots. Chaco also provides TraitsUI +views for configuring some Chaco objects. + +You will need at least a basic familiarity with TraitsUI for most Chaco +use cases. + +Kiva +---- + +`Kiva `_ provides an abstracted 2D drawing +API and a number of back-end implementations. This permits writing of +drawing code that can be used almost un-modified when rendering to a screen, +to a vector document format (such as PDF or PostScript), or to a raster file +format (such as PNG). + +The core object for Kiva code is the "graphics context" which represents a +2D drawing surface and the current state of the drawing environment. When +Chaco classes need to do any drawing they will usually be supplied with an +appropriate graphics context to render into, but very occasionally (such as +when saving a plot out to a file) you may want to create your own context to +draw into. + +If you want to write new Chaco overlays or plot renderers you should develop +an understanding of Kiva. + +Enable +------ + +`Enable `_ provides interactivity and layout +on top of the Kiva drawing library. Enable is the library that handles the +interface between Chaco plots and the OS/windowing system, as well as the +basic hierarchical layout and layering of visible components of a plot. + +Enable provides two base classes that are at the root of much of the Chaco +code: + +:py:class:`~enable.component.Component` + An object that occupies a rectangular region of the window and knows how + to + draw itself and dispatch user interactions. The + :py:class:`~enable.container.Container` class is a subclass of + :py:class:`~enable.component.Component` that handles hierarchical layout + and event dispatch. + + The drawing of :py:class:`~enable.component.Component` objects is split + across a number of layers, so that overlays, underlays, borders and + background can be rendered in a coherent manner. + +:py:class:`~enable.base_tool.BaseTool` + An object that handles a particular type of user interaction (eg. mouse + events or key presses). Each tool is a state machine and so the + interactions can vary depending on the state that the tool is in (eg. + "normal" vs. "dragging" state for a tool that handles moving + interactions). + +An understanding of Enable is important for writing new interactive tools, as +well as for understanding and controlling how components are layered and layed +out. + +Chaco Object Model +================== + +The :py:class:`~.chaco.plot.Plot` class provides a fairly simple API for +creating a plot in an application, but beneath that lies a set of classes +that handle converting the numbers in the numpy arrays into pixels on the +screen. Between the :py:class:`~.chaco.array_plot_data.ArrayPlotData` and the +:py:class:`~.chaco.plot.Plot` are a series of classes which hold state for +various operations and transformations. + +Data Flow +--------- + +The data flow between these classes can generally be sumarised as follows: + +.. graphviz:: + + digraph dataflow { + rankdir=LR; + node [shape=plaintext]; + "Plot Data" -> "Data sources" -> "Ranges" -> "Mappers" -> "Renderers" -> "Plot"; + "Data sources" -> "Renderers"; + "Mappers" -> "Axes and Grids"; + "Pan and Zoom" -> "Ranges"; + } + +Data sources + These hold individual data sets from the plot data (ie. something that + looks like a single NumPy array) and update when the data changes. + + Examples: :py:class:`~chaco.array_data_source.ArrayDataSource`, + :py:class:`~chaco.image_data.ImageData`, + :py:class:`~chaco.grid_data_source.GridDataSource`. + +Ranges + These hold a range of displayed data values and can be updated either + by changes to the data or changes in the state of pan or zoom tools. + + Examples: :py:class:`~chaco.data_range_1d.DataRange1D`, + :py:class:`~chaco.data_range_2d.DataRange2D`. + +Mappers + These are responsible for mapping data values to screen (or color) values. + + Examples: :py:class:`~chaco.linear_mapper.LinearMapper`, + :py:class:`~chaco.log_mapper.LogMapper`, + :py:class:`~chaco.grid_mapper.GridMapper`. + +Renderers + These are the objects responsible for rendering plot data, such as line + plots or scatter plots. They need to be update either when the data they + are displaying changes, or the mapping from data space to screen space + changes. + + Examples: :py:class:`~chaco.lineplot.LinePlot`, + :py:class:`~chaco.scatterplot.ScatterPlot`, + :py:class:`~chaco.cmap_image_plot.CMapImagePlot`, + :py:class:`~chaco.text_plot_1d.TextPlot1D`. + +Axes and Grids + These are the objects responsible for drawing axes ticks and grid lines, + and need to know the mapping between data space and screen space. Axes + and Grids are examples of Overlays (although they are technically + underlays). + + Examples: :py:class:`~chaco.axis.PlotAxis`, + :py:class:`~chaco.label_axis.LabelAxis`, + :py:class:`~chaco.grid.PlotGrid`. + +Pan and Zoom + These are pan and zoom commands that come from user interactions, such as + via a pan or zoom operation, from resizing the plot window, or from other + application-based setting of the range of values to display. Pan and zoom + are commonly initated via Tools. + + Examples: :py:class:`~chaco.tools.pan_tool.PanTool`, + :py:class:`~chaco.tools.zoom_tool.ZoomTool`. + +Data Flow Examples +~~~~~~~~~~~~~~~~~~ + +Consider the following example:: + + def create_plot(): + t = np.linspace(0, 2*np.pi, 100) + amplitude1 = 2*np.sin(t) + amplitude2 = np.cos(2*t) + plot_data = ArrayPlotData( + t=t, + amplitude1=amplitude1, + amplitude2=amplitude2, + ) + plot = Plot(plot_data) + plot.plot(('t', 'amplitude1'), type='line') + plot.plot(('t', 'amplitude2'), type='scatter') + return plot + +This sets up a number of objects and connects them together, so that data +flows roughly as follows: + +.. graphviz:: + + digraph dataflow { + + subgraph cluster_level { + node [shape=plaintext]; + style=invis; + "Data source" -> "Range" -> "Mapper" -> "Underlay" -> "Renderer" [style=invis]; + } + node [shape=rectangle]; + + subgraph index { + color=white; + "ArrayDataSource: time" -> "Range1D: index" -> "LinearMapper: index" -> "PlotAxis: index"; + } + subgraph value { + color=white; + "ArrayDataSource: amplitude1" -> "Range1D: value"; + "ArrayDataSource: amplitude2" -> "Range1D: value"; + "Range1D: value" -> "LinearMapper: value" -> "PlotAxis: value"; + } + + {rank = same; "Data source"; "ArrayDataSource: time"; "ArrayDataSource: amplitude1"; "ArrayDataSource: amplitude2"} + {rank = same; "Range"; "Range1D: index"; "Range1D: value"} + {rank = same; "Mapper"; "LinearMapper: index"; "LinearMapper: value"} + {rank = same; "Underlay"; "PlotAxis: index"; "PlotAxis: value"} + {rank = same; "Renderer"; "LinePlot"; "ScatterPlot"} + + "ArrayPlotData" -> "ArrayDataSource: time"; + "ArrayPlotData" -> "ArrayDataSource: amplitude1"; + "ArrayPlotData" -> "ArrayDataSource: amplitude2"; + "ArrayDataSource: time" -> "LinePlot"; + "ArrayDataSource: time" -> "ScatterPlot"; + "ArrayDataSource: amplitude1" -> "LinePlot"; + "ArrayDataSource: amplitude2" -> "ScatterPlot"; + "LinearMapper: value" -> "LinePlot"; + "LinearMapper: value" -> "ScatterPlot"; + "LinearMapper: index" -> "LinePlot"; + "LinearMapper: index" -> "ScatterPlot"; + "PlotAxis: index" -> "Plot"; + "PlotAxis: value" -> "Plot"; + "LinePlot" -> "Plot"; + "ScatterPlot" -> "Plot"; + } + +Updates to the data stored in the array plot data object trigger updates +through the pathways indicated, first updating the data sources for each +array, upon which the data ranges depend. In turn the mappers update their +state when the data ranges update, and the underlays and plot renderers +update their state based on changes to the mappers and, for the renderers, +on the changes to the data sources. Finally the changes to the state of the +components are flagged in the Enable drawing system, which will then schedule +the plot for re-drawing during the GUI event loop's next paint event. + +Notice also how this diagram shows that mappers and ranges are shared between +renderers and underlays that share the same physical space. Plots which don't +share the same screen space shouldn't share mappers, but can share data and/or +ranges. + +For example, here are two plots which share the same array plot data:: + + def create_plot(): + t = np.linspace(0, 2*np.pi, 100) + amplitude1 = 2*np.sin(t) + amplitude2 = np.cos(2*t) + plot_data = ArrayPlotData( + t=t, + amplitude1=amplitude1, + amplitude2=amplitude2, + ) + plot_1 = Plot(plot_data) + plot_1.plot(('t', 'amplitude1'), type='line') + plot_2 = Plot(plot_data) + plot_2.plot(('t', 'amplitude2'), type='scatter') + container = HPlotContainer(plot_1, plot2) + +Which gives rise to the following data flow diagram: + +.. graphviz:: + + digraph dataflow { + + subgraph cluster_level { + node [shape=plaintext]; + style=invis; + "Data source" -> "Range" -> "Mapper" -> "Underlay" -> "Renderer" [style=invis]; + } + node [shape=rectangle]; + + subgraph index_1 { + color=white; + "Range1D: index 1" -> "LinearMapper: index 1" -> "PlotAxis: index 1"; + } + subgraph value_1 { + color=white; + "Range1D: value 1" -> "LinearMapper: value 1" -> "PlotAxis: value 1"; + } + subgraph index_2 { + color=white; + "Range1D: index 2" -> "LinearMapper: index 2" -> "PlotAxis: index 2"; + } + subgraph value_2 { + color=white; + "Range1D: value 2" -> "LinearMapper: value 2" -> "PlotAxis: value 2"; + } + + {rank = same; "Data source"; "ArrayDataSource: time"; "ArrayDataSource: amplitude1"; "ArrayDataSource: amplitude2"} + {rank = same; "Range"; "Range1D: index 1"; "Range1D: value 1"; "Range1D: index 2"; "Range1D: value 2"} + {rank = same; "Mapper"; "LinearMapper: index 1"; "LinearMapper: value 1"; "LinearMapper: index 2"; "LinearMapper: value 2"} + {rank = same; "Underlay"; "PlotAxis: index 1"; "PlotAxis: value 1"; "PlotAxis: index 2"; "PlotAxis: value 2"} + {rank = same; "Renderer"; "LinePlot"; "ScatterPlot"} + + "ArrayPlotData" -> "ArrayDataSource: time"; + "ArrayPlotData" -> "ArrayDataSource: amplitude1"; + "ArrayPlotData" -> "ArrayDataSource: amplitude2"; + "ArrayDataSource: time" -> "Range1D: index 1" + "ArrayDataSource: time" -> "Range1D: index 2" + "ArrayDataSource: time" -> "LinePlot"; + "ArrayDataSource: time" -> "ScatterPlot"; + "ArrayDataSource: amplitude1" -> "Range1D: value 1"; + "ArrayDataSource: amplitude1" -> "Range1D: value 2"; + "ArrayDataSource: amplitude1" -> "LinePlot"; + "ArrayDataSource: amplitude2" -> "Range1D: value 1"; + "ArrayDataSource: amplitude2" -> "Range1D: value 2" + "ArrayDataSource: amplitude2" -> "ScatterPlot"; + "LinearMapper: value 1" -> "LinePlot"; + "LinearMapper: value 2" -> "ScatterPlot"; + "LinearMapper: index 1" -> "LinePlot"; + "LinearMapper: index 2" -> "ScatterPlot"; + "PlotAxis: index 1" -> "Plot 1"; + "PlotAxis: value 1" -> "Plot 1"; + "PlotAxis: index 2" -> "Plot 2"; + "PlotAxis: value 2" -> "Plot 2"; + "LinePlot" -> "Plot 1"; + "ScatterPlot" -> "Plot 2"; + } + +In contrast to the previous example the ranges and mappers are not related +in any way between the two plots. This means that changes to the visible +region in data space for one plot will not affect the other, and because +the values span a different range initially they will have different value +scales. + +It is common to want to share one or both of the ranges between plots to +keep the axes synchronized in data space. + +For example, here are two plots which share the same data ranges:: + + def create_plot(): + t = np.linspace(0, 2*np.pi, 100) + amplitude1 = 2*np.sin(t) + amplitude2 = np.cos(2*t) + plot_data = ArrayPlotData( + t=t, + amplitude1=amplitude1, + amplitude2=amplitude2, + ) + plot_1 = Plot(plot_data) + plot_1.plot(('t', 'amplitude1'), type='line') + plot_2 = Plot(plot_data) + plot_2.plot(('t', 'amplitude2'), type='scatter') + plot_2.index_range = plot_1.index_range + plot_2.value_range = plot_1.value_range + container = HPlotContainer(plot_1, plot2) + +Which gives rise to the following data flow diagram: + +.. graphviz:: + + digraph dataflow { + + subgraph cluster_level { + node [shape=plaintext]; + style=invis; + "Data source" -> "Range" -> "Mapper" -> "Underlay" -> "Renderer" [style=invis]; + } + node [shape=rectangle]; + + subgraph index_1 { + color=white; + "Range1D: index" -> "LinearMapper: index 1" -> "PlotAxis: index 1"; + } + subgraph value_1 { + color=white; + "Range1D: value" -> "LinearMapper: value 1" -> "PlotAxis: value 1"; + } + subgraph index_2 { + color=white; + "Range1D: index" -> "LinearMapper: index 2" -> "PlotAxis: index 2"; + } + subgraph value_2 { + color=white; + "Range1D: value" -> "LinearMapper: value 2" -> "PlotAxis: value 2"; + } + + {rank = same; "Data source"; "ArrayDataSource: time"; "ArrayDataSource: amplitude1"; "ArrayDataSource: amplitude2"} + {rank = same; "Range"; "Range1D: index"; "Range1D: value"} + {rank = same; "Mapper"; "LinearMapper: index 1"; "LinearMapper: value 1"; "LinearMapper: index 2"; "LinearMapper: value 2"} + {rank = same; "Underlay"; "PlotAxis: index 1"; "PlotAxis: value 1"; "PlotAxis: index 2"; "PlotAxis: value 2"} + {rank = same; "Renderer"; "LinePlot"; "ScatterPlot"} + + "ArrayPlotData" -> "ArrayDataSource: time"; + "ArrayPlotData" -> "ArrayDataSource: amplitude1"; + "ArrayPlotData" -> "ArrayDataSource: amplitude2"; + "ArrayDataSource: time" -> "Range1D: index"; + "ArrayDataSource: time" -> "LinePlot"; + "ArrayDataSource: time" -> "ScatterPlot"; + "ArrayDataSource: amplitude1" -> "Range1D: value"; + "ArrayDataSource: amplitude1" -> "LinePlot"; + "ArrayDataSource: amplitude2" -> "Range1D: value"; + "ArrayDataSource: amplitude2" -> "ScatterPlot"; + "LinearMapper: value 1" -> "LinePlot"; + "LinearMapper: value 2" -> "ScatterPlot"; + "LinearMapper: index 1" -> "LinePlot"; + "LinearMapper: index 2" -> "ScatterPlot"; + "PlotAxis: index 1" -> "Plot 1"; + "PlotAxis: value 1" -> "Plot 1"; + "PlotAxis: index 2" -> "Plot 2"; + "PlotAxis: value 2" -> "Plot 2"; + "LinePlot" -> "Plot 1"; + "ScatterPlot" -> "Plot 2"; + } + +Here any change to the range will automatically update the mappers +of both, so the visible ranges will match. However since the screen +space of the two plots is different, we don't want to share mappers +(mappers can only be shared when the plots are contained in an +:py:class:`~chaco.plot_containers.OverlayPlotContainer` or a +subclass such as :py:class:`~chaco.data_view.DataView` or +:py:class:`~chaco.plot.Plot`) + +Data Sources +------------ + +At its core, Chaco is about visualizing interactive data. As such, Chaco has +a standard API for representing data: all of these classes implement the +:py:class:`~chaco.abstract_data_source.AbstractDataSource` API. This class +has methods for getting and setting the data that is provided by the data +source, as well as basic information about the data's size and (for numerical +data) the numerical bounds of the values. A data source can also hold a +dictionary of arbitrary additional metadata. + +The workhorse data source is the +:py:class:`~chaco.array_data_source.ArrayDataSource` +which holds a single NumPy of array of numerical data and which covers almost +all common use cases. In most cases where you need to work with an +:py:class:`~chaco.array_data_source.ArrayDataSource` you call +:py:meth:`~chaco.array_data_source.ArrayDataSource.set_data` to change the +stored data, listen to the +:py:attr:`~chaco.abstract_data_source.AbstractDataSource.data_changed` event +trait for when the data changes and call +:py:meth:`~chaco.array_data_source.ArrayDataSource.get_data` to get the +current value of the data. + +Some users of a data source only care about the range of values that are +contained in that data. In this case the data source API provides a +:py:attr:`~chaco.abstract_data_source.AbstractDataSource.bounds_changed` trait +that indicates that the maximum or minimum value of the data has changed, and +those values can be efficiently retrieved via the +:py:meth:`~chaco.array_data_source.ArrayDataSource.get_bounds` trait. + +Similarly there is a +:py:attr:`~chaco.abstract_data_source.AbstractDataSource.metadata_changed` +event trait that is fired when the metadata dictionary is replaced or +modified. + +A common use case for alternative data sources is to render a computed +function (such as a curve that has been fit to the data) dynamically +rather than having to sample a fixed set of points. This can be done +by supplying the plot data with an +:py:class:`~chaco.function_data_source.FunctionDataSource` and plotting +that:: + + def create_plot(): + t = np.linspace(0, 2*np.pi, 100) + amplitude = 2*np.sin(t) + numpy.random.normal(scale=0.1) + plot_data = ArrayPlotData(t=t, amplitude=amplitude) + plot = Plot(plot_data) + plot.plot(('t', 'amplitude'), type='scatter') + + def f(low, high): + return 2*np.sin(np.linspace(low, high, 100)) + + data_source = FunctionDataSource( + func=f, data_range=plot.index_range + ) + plot_data.set_data('f', data_source) + plot.plot(('t', 'f'), type='line') + + return plot + +Mappers +------- + +Data as provided by the +:py:class:`~chaco.abstract_data_source.AbstractDataSource` is not suitable +for display; it needs to be mapped to an appropriate value for rendering +into a graphics context. The most obvious mapping transforms data values +into Enable's drawing coordinates (often simply referred to as "screen" +coordinates, whether or not they are actually rendered to a screen). +However similar transformations need to be performed to map numerical data +to color values for displaying on colormapped plots. There are two +hierarchies of classes that perform these transformations. + +The abstract base class for mapping data is the +:py:class:`~chaco.abstract_mapper.AbstractMapper` and this class +specifies methods +:py:meth:`~chaco.abstract_mapper.AbstractMapper.map_screen` for +mapping data values to screen values, +:py:meth:`~chaco.abstract_mapper.AbstractMapper.map_data` for +mapping screen values back to data values, and +:py:meth:`~chaco.abstract_mapper.AbstractMapper.map_data_array` +for mapping a collection of screen values to data values. Perhaps +most importantly, the mapper fires the +:py:attr:`~chaco.abstract_mapper.AbstractMapper.updated` event. + +Chaco provides a number of sub-classes of the base class for various +use-cases. The most commonly used is the +:py:class:`~chaco.linear_mapper.LinearMapper` which provides a one +dimensional linear transformation between data space and screen space, +but there is also :py:class:`~chaco.log_mapper.LogMapper` which provides +one dimensional logarithmic transformation, and +:py:class:`~chaco.grid_mapper.GridMapper` which provides a mapping frrom +a two dimensional data source to a point in screen (x, y) coordinates +using a combination of two one dimensional mappers. + +For mapping of values to colors, there is the +:py:class:`~chaco.abstract_colormap.AbstractColormap` class and +the two sub-classes :py:class:`~chaco.color_mapper.ColorMapper` and +:py:class:`~chaco.discrete_color_mapper.DiscreteColorMapper`. These have +the same base API as +:py:class:`~chaco.abstract_mapper.AbstractMapper` but also provide +some specialized methods for converting to integer RGB values efficiently. +Chaco provides a large number of default color maps suitable for various +visualization types. + +Ranges +------ + +A common problem to many data mappers is that the range of data values +may change dynamically, and when data changes it is desirable to have +the mapper automatically update itself to ensure that the full range of +data values is mapped to the screen. This functionality is broken out +into subclasses of the +:py:class:`~chaco.abstract_data_range.AbstractDataRange` class. + +These classes track a collection of +:py:class:`~chaco.abstract_data_source.AbstractDataSource` instances via +their :py:attr:`~chaco.abstract_data_range.AbstractDataRange.sources` +trait, and when the bounds of any of those data sources change then +the range adjusts its upper and lower bound appropriately. Data mappers +then listen to the values of the upper and lower bounds of the range and +use that to adjust the transformation that they apply. The actual +values of the upper and lower bounds in data space coordinates are +provided by the :py:attr:`~chaco.abstract_data_range.AbstractDataRange.low` +and :py:attr:`~chaco.abstract_data_range.AbstractDataRange.high` traits. + +However there are situations where the behaviour of the range should +change, for example after a pan or zoom operation the value of the +bounds should remain fixed to whatever values the user panned or zoomed +to even if the underlying data changes. For these purposes, code +interacting with a data range can set the +:py:attr:`~chaco.abstract_data_range.AbstractDataRange.low_setting` and +:py:attr:`~chaco.abstract_data_range.AbstractDataRange.high_setting` traits +either to an absolute numerical value in the data space, or to a number of +other values, such as ``auto`` or ``track`` that determine the behaviour +when data changes. + +The most commonly used subclass is +:py:class:`~chaco.data_range_1d.DataRange1D` which has a number of +additional affordances to facilitate pleasant appearing plots, such as +the ability to add some padding above and below the data via the +:py:attr:`~chaco.data_range_1d.DataRange1D.margin` trait, or even +to supply a custom padding calculation function. + +It is worthwhile noting that data ranges can be shared between mappers, +and this permits linking of axes bounds or color maps ranges across +different plots. + +Axes and Grids +-------------- + +Axes and grids are auxilliary objects that draw plot decorations. +They are underlays (and so inherit from +:py:class:`~chaco.abstract_overlay.AbstractOverlay`) and are +usually drawn into the underlay layer of a :py:class:`~chaco.plot.Plot` +but they are also able to be used as stand-alone components if needed +(for example to create multi-axis plots). + +These objects present numerous options for their styling, but perhaps +more importantly allow control over the algorithm to used for determining +where tick marks and grid lines should be drawn. Both classes have a +:py:attr:`tick_generator` trait which takes an instance of an +:py:class:`~chaco.ticks.AbstractTickGenerator` which has a single +method :py:meth:`~chaco.ticks.AbstractTickGenerator.get_ticks` that +returns the tick positions for the current data and screen space bounds. + +There are several standard tick generators available for use, +but in the absence of anything else the +:py:class:`~chaco.ticks.DefaultTickGenerator` is used, which tries to +generate genererally pleasing ticks at round numbers for both linear +and logarithmic mappings. The +:py:class:`~chaco.ticks.MinorTickGenerator` is similar, but generates +generate denser ticks that are suitable for use as a minor scale. The +:py:class:`~chaco.ticks.ShowAllTickGenerator` simply shows ticks at +a list of supplied data values, giving complete control at the expense +of not being able to dynamically adapt to changes from panning and +zooming. + +For more complex tick generation, such as time axes where the "natural" +tick spacings, positions and even label formatting can change as you +zoom through different levels, the +:py:class:`~chaco.scales_tick_generator.ScalesTickGenerator` allows the +user to specify a multi-leveled +:py:class:`~chaco.scales.scales.ScaleSystem`. In particular this system +provides the :py:class:`~chaco.scales.time_scale.CalendarScaleSystem` +which by default correct ticks axes with time values ranging from microseconds +through to years. + +For example, you can create an hours, minutes, seconds time axis (ignoring +higher level calendar constructs) for a plot as follows:: + + from chaco.scales.api import ( + CalendarScaleSystem, HMSScales, ScalesTickGenerator + ) + + def create_plot(): + t = np.linspace(0, 3600, 36001) + a = np.sin(2*pi*60*t) + plot_data = ArrayPlotData(t=t, a=a) + plot = Plot(plot_data) + plot.plot(('t', 'a'), type='line') + plot.index_axis.tick_generator = ScalesTickGenerator( + scale=CalendarScaleSystem(*HMSScales) + ) + + return plot + +Plot Renderers +-------------- + +The core of the Chaco plotting library are the plot renderers which are +responsible for drawing the markings that represent the data, all of which +implement the :py:class:`~chaco.abstract_plot_renderer.AbstractPlotRenderer` +API. This ABC is a subclass of +:py:class:`~chaco.plot_component.PlotComponent`, and so all plot renderers +are expected to implement the key parts of the Enable drawing API. Most +specialized plot renderers expect a :py:meth:`render` method that performs +actual drawing of the plot into a provided Kiva graphics context. + +Most plot renders have the notion of "index" and "value" data that +they are plotting. Each item in the index has a corresponding value, so if +a function were being plotted the index are points in the domain and the +values are points in the range. For plot renderers the index usually +provides a location at which the value should be rendered, and the value +provides a position offset or color value. Importantly, the index and value +are not directly linked to horizontal or vertical screen space. + +Different subclasses of the abstract plot renderer implement common +conventions for handling index and value representation. For example: + +:py:class:`~chaco.base_xy_plot.BaseXYPlot` + This class handles plots like line plots and bar plots where the index + gives offsets along one axis and the values are along the other axis. + +:py:class:`~chaco.base_1d_plot.Base1DPlot` + This class handles plots where the index gives the offset along one + axis, and the values are displayed by markings at or near those points. + +:py:class:`~chaco.base_2d_plot.Base2DPlot` + This class handles plots like contour and image plots where the + index lies on a regular 2D grid and values are displayed by markings + at or near those points. + +There are a number of other plot types that handle special cases like +candle plots. + +Plot renderers have mappers for each of their data dimensions, but they +also express convenience APIs mapping data values to and from screen +(x, y) values using the methods +:py:meth:`~chaco.abstract_plot_renderer.AbstractPlotRenderer.map_data` +and +:py:meth:`~chaco.abstract_plot_renderer.AbstractPlotRenderer.map_screen`. +These are usually simple wrappers around the appropriate mapper calls of +the same name. + +Plot renderers also have to provide information for tools that want to +interact with the values on the plot. They are expected to provide a +:py:meth:`~chaco.abstract_plot_renderer.AbstractPlotRenderer.map_index` +method which handles mapping a screen point to an index item (ie. an +integer index into the index data source). + +Tools +----- + +Up to this point, all the classes discussed are dynamic in the sense +that if the underlying data changes then the visualization will update +appropriately. However it is often the case that you want to add other +interactions to a visualization. The most common of these is the +ability to pan or zoom the plot to focus on particular details, but +there number of ways that you might want a user to interact with the +visualization is potentially vast. As a result one of the most common +ways to customize a visualization is by writing new tools. + +Tools are technically a feature of Enable, rather than Chaco, and as +a result there are a number of tools and base classes there that can +be used as the foundation or inspiration for custom interactions. For +example, the following Enable tools may be of use: + +:py:class:`enable.tools.move_tool.MoveTool` + A tool which changes the screen location of a component by dragging + with the mouse. This can be useful for allowing the user to move + plot decorations such as legends around the plot. + +:py:class:`enable.tools.resize_tool.ResizeTool` + A tool which changes the screen size of a component by dragging + edges or corners. + +:py:class:`enable.tools.hover_tool.HoverTool` + A tool which calls a callback when the mouse hs not moved + significantly for a period of time. + +:py:class:`enable.tools.button_tool.ButtonTool` + A tool that makes a component act like a button, with a + :py:class:`enable.tools.button_tool.ButtonTool.clicked` + trait that you can react to via the usual Traits mechanisms. + +:py:class:`enable.tools.pyface.context_menu_tool.ContextMenuTool` + A tool which displays a context menu at the point where the + use right-clicks, using Pyface's menu and action classes. + +:py:class:`enable.tools.traits_tool.TraitsTool` + A tool which opens a TraitsUI dialog when a component is + double-clicked. + +:py:class:`enable.tools.base_drop_tool.BaseDropTool` + A base tool which responds to operating system drag and drop. + Must be subclassed to implement methods that indicate whether + a type of object can be dropped, and what to do if they are + dropped. + +:py:class:`enable.tools.value_drag_tool.ValueDragTool` + A base tool which changes a numeric value as the user + drags the mouse. Must be subclassed to provide methods to + get and set the value. There is a subclass + :py:class:`enable.tools.value_drag_tool.AttributeDragTool` + which sets the values of attributes on an object as the + mouse moves, which is a common use case. + +Overlays and Underlays +---------------------- + +In some instances you want to render additional decorations that are +independent of the plot type. In a similar fashion to the Tool classes +auxilliary renderers can be attached to plots as "overlays" (and using +the same mechanism, just rendering into a different layer, as +"underlays"). Common use cases for overlays include cursor lines, +selection regions, hover text, legends and other annotations. Overlays +are frequently designed to work together with a particular Tool or class +of tools, but can frequently be used independently if desired. + +Overlays and underlays which need to render relative to points in +data space will frequently want to make use of the plot mappers to know +where in screen space to perform their drawing operations.. + diff --git a/docs/source/developer_reference/index.rst b/docs/source/developer_reference/index.rst new file mode 100644 index 000000000..f17868929 --- /dev/null +++ b/docs/source/developer_reference/index.rst @@ -0,0 +1,19 @@ +:orphan: + +.. _developer_reference: + +=================== +Developer Reference +=================== + +This reference is designed to provide a guide to developers wanting to extend +the capabilities of Chaco by writing new tools, overlays and plot renders. +For complete details of the interfaces and base classes that you will need +to use, refer to the Chaco :ref:`API documentation `. + +.. toctree:: + :maxdepth: 2 + + fundamentals.rst + architecture_overview + diff --git a/docs/source/index.rst b/docs/source/index.rst index f510743ce..0b93470dc 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -2,14 +2,17 @@ Chaco |version| =============== Chaco is a Python package for building interactive and custom 2-D plots and -visualizations. -Chaco facilitates writing -plotting applications at all levels of complexity, from simple scripts with -hard-coded data to large plotting programs with complex data interrelationships -and a multitude of interactive tools. While Chaco generates attractive static -plots for publication and presentation, it also works well for interactive -data visualization and exploration. -Chaco is part of the `Enthought Tool Suite `_. +visualizations. Chaco facilitates writing plotting applications at all levels +of complexity, from simple scripts with hard-coded data to large plotting +programs with complex data interrelationships and a multitude of interactive +tools. While Chaco generates attractive static plots for publication and +presentation, Chaco differs from tools like MatPlotLib in that it also works +well for dynamic interactive data visualization and exploration. Chaco is part +of the Enthought Tool Suite. + +.. image:: images/chaco_show.png + :width: 800 px + :align: center Chaco includes renderers for many popular plot types, built-in implementations of common interactions with those plots, and a framework for extending and @@ -17,33 +20,63 @@ customizing plots and interactions. Chaco can also render graphics in a non-interactive fashion to images, in either raster or vector formats, and it has a subpackage for doing command-line plotting or simple scripting. -For a quick sample of Chaco's features, see the -`gallery `_, the -:ref:`annotated examples ` page, the -:ref:`tutorial and examples ` -and the :ref:`resources ` page. +Installation +------------ +Chaco and all of its dependencies (including the PyQt backend) can be +installed using the `Enthought Deployment Manager +`_ (formerly +EPD): +.. code-block:: console + + edm install chaco pyqt5 + +For full installation options, including installation from source, see the +:ref:`installation instructions `. Documentation ------------- -.. toctree:: - :maxdepth: 1 +For developers exploring Chaco for the first time, these tutorials and examples +give a good overview of the capabilities of Chaco: - Installation and quickstart guide - user_manual/tutorials_and_examples.rst - user_manual/index.rst - user_manual/resources.rst - programmers_reference.rst - tech_notes.rst +* :ref:`Sample Plot Gallery ` +* :ref:`Tutorial: Interactive plotting with Chaco ` +* :ref:`Tutorial: Using Chaco from IPython ` +* Examples: ------------- + - :ref:`Modeling Van del Waal's Equations ` + - :ref:`Creating an interactive Hyetograph ` -.. image:: images/chaco_show.png - :width: 800 px - :align: center +There is also a :ref:`FAQ ` which provides answers to issues and common +tricks that help when building Chaco applications. ------------- +For comprehensive documentation, we have: +* :ref:`User Guide ` +* :ref:`Developer Reference ` +* :ref:`API Reference ` * :ref:`search` + +Reporting bugs and contributing +------------------------------- + +Since Chaco is open source and hosted on +`Github `_, the development version can +always be checked out from Github, forked, and modified at will. When a bug is +found, please submit an issue in the +`issue page `_. If you would like to +share a bug fix or a new feature, simply submit a Pull Request from your fork. +Don't forget to specify very clearly what code to run to reproduce the issue, +what the logic of the fix is and to add one or more unit tests to ensure future +stability. The Pull Request description can and often needs to contain +screenshots of the issue or the fix. + +License +------- + +As part of the `Enthought Tool Suite `_, Chaco is +free and open source under a BSD license: + +.. include:: ../../LICENSE.txt diff --git a/docs/source/modules_and_classes.rst b/docs/source/modules_and_classes.rst deleted file mode 100644 index f75285ab9..000000000 --- a/docs/source/modules_and_classes.rst +++ /dev/null @@ -1,245 +0,0 @@ - -.. _modules_and_classes: - -Commonly Used Modules and Classes -================================= - -Base Classes ------------------------------------------------------------------------------ - -.. rubric:: Plot Component - -All visual components in Chaco subclass from :class:`PlotComponent`. It defines -all of the common visual attributes like background color, border styles and -color, and whether the component is visible. (Actually, most of these visual -attributes are inherited from the Enable drawing framework.) More importantly, -it provides the base behaviors for participating in layout, handling event -dispatch to tools and overlays, and drawing various layers in the correct order. -Subclasses almost never need to override or customize these base behaviors, but -if they do, there are several easy extension points. - -PlotComponent is a subclass of Enable :class:`Component`. It has its -own default drawing order. It redefines the inherited traits :attr:`draw_order` -and :attr:`draw_layer`, but it doesn't define any new traits. Therefore, you -may need to refer to the API documentation for Enable Component, -even when you have subclassed Chaco PlotComponent. - -If you subclass PlotComponent, you need to implement :meth:`do_layout`, -if you want to size the component correctly. - - -Data Objects ------------------------------------------------------------------------------ - -.. rubric:: Data Source - -A data source is a wrapper object for the actual data that it will be -handling. It provides methods for retrieving data, estimating a size of the -dataset, indications about the dimensionality of the data, a place for metadata -(such as selections and annotations), and events that fire when the data gets -changed. There are two primary reasons for a data source class: - -* It provides a way for different plotting objects to reference the same data. -* It defines the interface for embedding Chaco into an existing application. - In most cases, the standard ArrayDataSource will suffice. - - *Interface:* :class:`AbstractDataSource` - - *Subclasses:* :class:`ArrayDataSource`, :class:`MultiArrayDataSource`, - :class:`PointDataSource`, :class:`GridDataSource`, :class:`ImageData` - -.. rubric:: Data Range - -A data range expresses bounds on data space of some dimensionality. The simplest -data range is just a set of two scalars representing (low, high) bounds in 1-D. -One of the important aspects of data ranges is that their bounds can be set to -``auto``, which means that they automatically scale to fit their associated -datasources. (Each data source can be associated with multiple ranges, -and each data range can be associated with multiple data sources.) - - *Interface*: :class:`AbstractDataRange` - - *Subclasses*: :class:`BaseDataRange`, :class:`DataRange1D`, - :class:`DataRange2D` - -.. rubric:: Data Source - -A data source is an object that supplies data to Chaco. For the most part, a -data source looks like an array of values, with an optional mask and metadata. - - *Interface*: :class:AbstractDataSource` - - *Subclasses*: :class:`ArrayDataSource`, :class:`DataContextDataSource`, - :class:`GridDataSource`, :class:`ImageData`, :class:`MultiArrayDataSource`, - :class:`PointDataSource` - -The :attr:`metadata` trait attribute is a dictionary where you can stick -stuff for other tools to find, without inserting it in the actual data. - -Events that are fired on data sources are: - - * :attr:`data_changed` - * :attr:`bounds_changed` - * :attr:`metadata_changed` - - -.. rubric:: Mapper - -Mappers perform the job of mapping a data space region to screen space, and -vice versa. Bounds on mappers are set by data range objects. - - *Interface*: :class:`AbstractMapper` - - *Subclasses*: :class:`Base1DMapper`, :class:`LinearMapper`, - :class:`LogMapper`, :class:`GridMapper`, :class:`PolarMapper` - - -Containers ------------------------------------------------------------------------------ - -.. rubric:: PlotContainer - -:class:`PlotContainer` is Chaco's way of handling layout. Because it logically -partitions the screen space, it also serves as a way for efficient event -dispatch. It is very similar to sizers or layout grids in GUI toolkits like -WX. Containers are subclasses of PlotComponent, thus allowing them to -be nested. :class:`BasePlotContainer` implements the logic to correctly render -and dispatch events to sub-components, while its subclasses implement the -different layout calculations. - -A container gets the preferred size from its components, and tries to allocate -space for them. Non-resizeable components get their required size; whatever is -left over is divided among the resizeable components. - -Chaco currently has three types of containers, -described in the following sections. - - *Interface*: :class:`BasePlotContainer` - - *Subclasses*: :class:`OverlayPlotContainer`, :class:`HPlotContainer`, - :class:`VPlotContainer`, :class:`GridPlotContainer` - -The listed subclasses are defined in the module -:mod:`chaco.plot_containers`. - - -Renderers ------------------------------------------------------------------------------ - -Plot renderers are the classes that actually draw a type of plot. - - *Interface*: :class:`AbstractPlotRenderer` - *Subclasses*: - - * :class:`BarPlot` - * :class:`Base2DPlot` - - * :class:`ContourLinePlot` - * :class:`ContourPolyPlot` - * :class:`ImagePlot`: displays an image file, or color-maps scalar - data to make an image - * :class:`CMapImagePlot` - - * :class:`BaseXYPlot`: This class is often emulated by writers of other - plot renderers, but renderers don't *need* to be structured this way. - By convention, many have a :meth:`hittest` method. They *do* need - to implement :meth:`map_screen`, :meth:`map_data`, and :meth:`map_index` - from :class:`AbstractPlotRenderer`. - - * :class:`LinePlot` - - * :class:`ErrorBarPlot` - - * :class:`PolygonPlot` - - * :class:`FilledLinePlot` - - * :class:`ScatterPlot` - - * :class:`ColormappedScatterPlot` - - * :class:`ColorBar` - * :class:`PolarLineRenderer`: NOTE: doesn't play well with others - -You can use these classes to compose more interesting plots. - -The module :mod:`chaco.plot_factory` contains various convenience -functions for creating plots, which simplify the set-up. - -The :class:`chaco.plot.Plot` class (called "capital P Plot" when -speaking) represents what the user usually thinks of as a "plot": a set of data, -renderers, and axes in a single screen region. It is a subclass of -:class:`DataView`. - -Tools ------------------------------------------------------------------------------ - -Tools attach to a component, which gives events to the tool. - -All tools subclass from Enable's :class:`BaseTool`, which is in turn an Enable -:class:`Interactor`. Do not try to make tools that draw: use an overlay for -that. - -Some tool subclasses exist in both Enable and Chaco, because they were created -first in Chaco, and then moved into Enable. - - *Interface*: :class:`BaseTool` - *Subclasses*: - - * :class:`BroadcasterTool`: Keeps a list of other tools, and broadcasts - events it receives to all those tools. - * :class:`DataPrinter`: Prints the data-space position of the point - under the cursor. - * :class:`enable.tools.api.DragTool`: Enable base class - for tools that do dragging. - - * :class:`MoveTool` - * :class:`ResizeTool` - * :class:`ViewportPanTool` - - * :class:`chaco.tools.api.DragTool`: Chaco base class - for tools that do dragging. - - * :class:`BaseCursorTool` - - * :class:`CursorTool1D` - * :class:`CursorTool2D` - - * :class:`DataLabelTool` - * :class:`DragZoom` - * :class:`LegendTool` - * :class:`MoveTool` - - * :class:`DrawPointsTool` - * :class:`HighlightTool` - * :class:`HoverTool` - * :class:`ImageInspectorTool` - * :class:`LineInspector` - * :class:`PanTool` - - * :class:`TrackingPanTool` - - * :class:`PointMarker` - * :class:`SaveTool` - * :class:`SelectTool` - - * :class:`ScatterInspector` - * :class:`SelectableLegend` - - * :class:`enable.tools.api.TraitsTool` - * :class:`chaco.tools.api.TraitsTool` - - - -DragTool is a base class for tools that do dragging. - -Other tools do things like panning, moving, highlighting, line segments, range selection, drag zoom, move data labels, scatter inspection, Traits UI. - -Overlays ------------------------------------------------------------------------------ - - -Miscellaneous ------------------------------------------------------------------------------ - - diff --git a/docs/source/programmers_reference.rst b/docs/source/programmers_reference.rst deleted file mode 100644 index aa78bf5bc..000000000 --- a/docs/source/programmers_reference.rst +++ /dev/null @@ -1,21 +0,0 @@ - -.. _programmers_reference: - -Programmer's Reference -====================== - -.. toctree:: - :maxdepth: 2 - - architecture_overview.rst - modules_and_classes.rst - api/data_sources.rst - api/data_ranges.rst - api/mappers.rst - api/containers.rst - api/visual_components.rst - api/renderers.rst - api/plot_factories.rst - api/axis.rst - api/tools.rst - \ No newline at end of file diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst deleted file mode 100644 index 92854b8d1..000000000 --- a/docs/source/quickstart.rst +++ /dev/null @@ -1,381 +0,0 @@ -########## -Quickstart -########## - - -+----------------------------------------+--------------------------------------+ -|.. image:: images/simple_line.png |.. image:: images/scalar_function.png| -| :height: 300 px | :height: 300 px | -| :align: center | :align: center | -+----------------------------------------+--------------------------------------+ - -This section is meant to help users on well-supported platforms and common -Python environments get started using Chaco as quickly as possible. - -Installation -============ - -There are several ways to get Chaco. The easiest way is through `Enthought -Canopy (Canopy) `_ (formerly EPD) -which is available for Windows, Linux and Mac OSX and also provides many other -useful packages. Chaco may also be available through a package manager on your -platform, such as apt on Ubuntu, yum on Redhat or -`MacPorts `_ on OS X. You can also build Chaco from -its `source code `_, but because of the -dependencies, the easiest way by far is to install Canopy. - -.. _dependencies: - -Dependencies ------------- - -* `Python `_ 2.7 or later - -* `Traits `_, an event notification - framework - -* `Kiva `_, part of the enable project, - for rendering 2-D graphics to a variety of backends across platforms - -* `Enable `_, a framework for writing - interactive visual components, and for abstracting away GUI-toolkit-specific - details of mouse and keyboard handling. - -* `NumPy `_, for dealing efficiently with large - datasets - -* Either `wxPython `_, `PyQt - `_ (GPL or - Commercial license) or `PySide `_ (LGPL license) to - display interactive plots. - -Installing Chaco with Canopy ----------------------------- - -Chaco, the rest of the `Enthought Tool Suite `_, -and a lot more are bundled with Enthought Canopy (formerly EPD). Getting -Canopy gives you a one-click install of Chaco -and all its dependencies at once; however, these packages will be linked to a -new instance of Python. Canopy Express is free for all users and -contains all that you need to use Chaco. - -To get Canopy, go to the `Canopy download page -`_, select the desired bundle (Express, Full, -TriplePlay) and get the appropriate version for your platform. After running -the installer, you will have a working version of Chaco and several examples. - -Building Chaco ---------------- - -Building Chaco on your machine requires you to build Chaco and each of its -dependencies, but it has the advantage of installing Chaco on top of the Python -instance you already have installed. The build process may be challenging and -will require you to have a C compiler, SWIG, Cython and several development -libraries installed. - -To do this, you can either: - -1. Install Chaco and its :ref:`dependencies` from `PyPI - `_ using - `pip `_ or using `easy_install - `_ (part of - setuptools). For example - - :command:`pip install chaco` - -.. note:: - If you have already installed Chaco and just want to update to the newest - version, use - - :command:`pip install --upgrade chaco` - -2. Or, download the source from the `Chaco GitHub repository - `_ or alternatively as a part of the - full `Enthought Tool Suite `_. - -.. Please refer to the :ref:`installation` section for more detailed -.. instructions. -.. TODO This 'installation' section does not currently exist - - -Built-in Examples -================= - -Chaco ships with several examples for testing your installation and to show you -what Chaco can do. Almost all of the examples are stand-alone files that you -can run individually, from any location. Depending on how you installed Chaco, -you may or may not have the examples already. - -Location --------- - -1. If you installed Chaco as part of Canopy, the location of the examples depends - on your platform: - - * On Windows, they are in the Examples\\ subdirectory of your installation - location. This is typically - :file:`C:\\Users\\\\AppData\\Local\\Enthought\\Canopy\\User\\Examples\\Chaco-`. - These examples can be browsed from the start menu, by clicking - :menuselection:`Start --> Applications --> Enthought Canopy --> Example Browser`. - - * On Linux, they are in the - :file:`Enthought/Canopy_XXbit/User/Examples/Chaco-` - subdirectory of your installation location. - - * On Mac OS X, they are in the - :file:`/Library/Enthought/Canopy_XXbit/User/Examples/chaco-` - directory. - -2. If you downloaded and installed Chaco from source (from GitHub or via the - PyPI tar.gz file), the examples are located in the :file:`examples/` - subdirectory inside the root of the Chaco source tree, next to :file:`docs/` - and the :file:`chaco/` directories. - -3. If you don't know how Chaco was installed, you can download the latest - versions of examples individually from github: - - https://github.com/enthought/chaco/tree/master/examples - -Chaco examples can be found in the :file:`examples/demo/` and -:file:`examples/tutorials/` directories. Some are classified by themes and -located in separate directories. Almost all of the Chaco examples are -standalone files that can be run individually. We will first show how to -execute them from the command line, and then we will show how to run Chaco in -an interactive way from IPython. This "shell" mode will be more familiar to -Matplotlib or Matlab users. - -.. note:: - Some of these examples can be visualized in our - `Chaco gallery `_. - - -First plots from the command line ---------------------------------- - -From the :file:`examples/demo` directory, run the ``simple_line`` example: - - :command:`python simple_line.py` - -This opens a plot of several Bessel functions with a legend. - - .. image:: images/simple_line.png - -You can interact with the plot in several ways: - -.. Ctrl-Left and Ctrl-Right don't work in OS X? - -* To pan the plot, hold down the left mouse button inside the plot area (but - not on the legend) and drag the mouse. - -* To zoom the plot: - - * Mouse wheel: scroll up to zoom in, and scroll down to zoom out (or the - reverse you're on a version of OS X with 'natural scrolling'). - - * Zoom box: Press :kbd:`z`, and then draw a box region to zoom in on. - (There is no box-based zoom out.) Press :kbd:`Ctrl-Left` and - :kbd:`Ctrl-Right` to go back and forward in your zoom box history. - - * Drag: hold down the right mouse button and drag the mouse up or down. Up - zooms in, and down zooms out. - - * For any of the above, press :kbd:`Escape` to reset the zoom to the - original view. - -* To move the legend, hold down the right mouse button inside the legend and - drag it around. Note that you can move the legend outside of the plot area. - -* To exit the plot, click the "close window" button on the window frame or (on - Mac) choose the Quit option on the Python menu. Alternatively, can you press - :kbd:`Ctrl-C` in the terminal. - -You can run most of the examples in the the :file:`examples/demo/basic/` -directory and the :file:`examples/demo/shell/` directory. The -:file:`examples/demo/advanced/` directory has some examples that require -additional data or packages. In particular, - -* :file:`spectrum.py` requires that you have PyAudio installed and a working - microphone. - -* :file:`data_cube.py` needs to download about 7.3mb of data from the Internet - the first time it is executed, so you must have a working Internet - connection. Once the data is downloaded, you can save it so you can run the - example offline in the future. - -For detailed information about each built-in example, see the :ref:`examples` -section. - - -First plots from IPython ------------------------- - -While all of the Chaco examples can be launched from the command line using the -standard Python interpreter, if you have IPython installed, you can poke around -them in a more interactive fashion. - -Chaco provides a subpackage, currently named the "Chaco Shell", for doing -command-line plotting like Matlab or Matplotlib. The examples in the -:file:`examples/demo/shell/` directory use this subpackage, and they are -particularly amenable to exploration with IPython. - -The first example we'll look at is the :file:`lines.py` example. First, we'll -run it using the standard Python interpreter: - - :command:`python lines.py` - -This shows two overlapping line plots. - -.. image:: images/lines.png - -You can interact with this plot just as in the previous section. - -Now close the plot, and start IPython with the ``--gui=qt`` [#guiqt]_ or -``--gui=wx`` option: - - :command:`ipython --gui=qt` - -This tells IPython to start a Qt or Wx mainloop in a background thread. Now -run the previous example again:: - - In [1]: run lines.py - -This displays the plot window, but gives you another IPython prompt. You can -now use various commands from the :mod:`chaco.shell` package to interact with -the plot. - -Import the shell commands:: - - In [2]: from chaco.shell import * - -Set the X-axis title:: - - In [3]: xtitle("X data") - -Toggle the legend:: - - In [4]: legend() - -After running these commands, your plot looks like this: - -.. image:: images/lines_final.png - -The :func:`chaco_commands` function display a list of commands with brief -descriptions. - -You can explore the Chaco object hierarchy, as well. The :mod:`chaco.shell` -commands are just convenience functions that wrap a rich object hierarchy that -comprise the actual plot. See the :ref:`tutorial_ipython` section for -information on all you can do with Chaco from within IPython. - - -Chaco plot embedded in a Traits application -=========================================== - -The previous section showed how Chaco can be used interactively similarly to -`Matlab` or Matplotlib's `pyplot` package - -Now, let's create, from scratch, the simplest possible Chaco plot which is -embedded inside a `Traits`_ application. This will require more work but will -represent the basis for a potential large-scale, custom and powerful rich -client application. this is really what Chaco has been written for. - -First, some imports to bring in necessary components:: - - from chaco.api import ArrayPlotData, Plot - from enable.component_editor import ComponentEditor - - from traits.api import HasTraits, Instance - from traitsui.api import View, Item - -The imports from :mod:`chaco` and :mod:`enable` support the creation of the -plot. The imports from :mod:`traits` bring in components to embed the plot -inside a Traits application. (Refer to the `Traits documentation -`_ for more details about building an -interactive application using Traits.) Now let's create a Traits class with a -view that contains only one element: a Chaco plot inside a slightly customized -window:: - - class MyPlot(HasTraits): - plot = Instance(Plot) - traits_view = View(Item('plot', editor = ComponentEditor(), show_label = False), - width = 500, height = 500, - resizable = True, title = "My line plot") - -A few options have been set to control the window containing the plot. Now, -when the plot is created, we would like to pass in our data. Let's assume the -data is a set of points with coordinates contained in two NumPy arrays ``x`` -and `y`. So, adding an ``__init__`` method to create the Plot object looks as -follows:: - - class MyPlot(HasTraits): - plot = Instance(Plot) - traits_view = View(Item('plot', editor = ComponentEditor(), show_label = False), - width = 500, height = 500, - resizable = True, title = "My line plot") - - def __init__(self, x, y, *args, **kw): - super(MyPlot, self).__init__(*args, **kw) - plotdata = ArrayPlotData(x=x,y=y) - plot = Plot(plotdata) - plot.plot(("x","y"), type = "line", color = "blue") - plot.title = "sin(x)*x**3" - self.plot = plot - -Since it inherits from HasTraits, the new class can use all the power of -Traits, and the call to super() in its ``__init__`` method makes sure this -object possesses the attributes and methods of its parent class. Now let's use -our Traits object. Below, we generate some data, pass it to an instance of -MyPlot and call configure_traits to create the UI:: - - import numpy as np - x = np.linspace(-14,14,100) - y = np.sin(x)*x**3 - lineplot = MyPlot(x,y) - lineplot.configure_traits() - -The result should look like - -.. image:: images/mylineplot.png - -This might look like a lot of code to visualize a function, but this is a -relatively simple basis on top of which we can build full-featured applications -with custom UIs and custom tools. For example, the Traits object allows you to -create controls for your plot at a very high level, add these controls to the -UI with very little work, and add listeners to update the plot when the data -changes. Chaco also allows you to create custom tools to interact with the -plot and overlays that make these tools intuitive and visually appealing. - - -.. rubric:: Footnotes - -.. [#guiqt] Starting from IPython 0.12, it is possible to use the Qt backend - with ``--gui=qt``. Make sure that the environment variable ``QT_API`` - is set correctly, as described `here - `_ - -Where to learn more? -==================== - -To learn more about the power of Chaco and to build powerful rich client -applications with custom visualizations, consider going over the -:ref:`tutorials` section or learning from the :ref:`user_guide`. - -License -======= - -As part of the `Enthought Tool Suite `_, Chaco is -free and open source under the BSD license. - -Reporting bugs and contributing -=============================== - -Since Chaco is open source and hosted on -`Github `_, the development version can -always be checked out from Github, forked, and modified at will. When a bug is -found, please submit an issue in the -`issue page `_. If you would like to -share a bug fix or a new feature, simply submit a Pull Request from your fork. -Don't forget to specify very clearly what code to run to reproduce the issue, -what the logic of the fix is and to add one or more unit tests to ensure future -stability. The Pull Request description can and often needs to contain -screenshots of the issue or the fix. diff --git a/docs/scipy08_tutorial.pdf b/docs/source/resources/scipy08_tutorial.pdf similarity index 100% rename from docs/scipy08_tutorial.pdf rename to docs/source/resources/scipy08_tutorial.pdf diff --git a/docs/source/user_manual/basic_elements/overlays.rst b/docs/source/user_manual/basic_elements/overlays.rst index c3b88d934..5008e1af5 100644 --- a/docs/source/user_manual/basic_elements/overlays.rst +++ b/docs/source/user_manual/basic_elements/overlays.rst @@ -1,6 +1,6 @@ -================================== +########################## Overlays: Axis, Grid, etc. -================================== +########################## Overlays are elements that decorate plots, like for example axes, legends, grids, etc. @@ -19,8 +19,11 @@ is 'transparent' by default; 3) they plot :ref:`on the 'overlay' layer ` by default. -TODO: explain how to attach an overlay to an existing plot renderer +.. TODO: explain how to attach an overlay to an existing plot renderer +============= +Core Overlays +============= There are three important classes of overlays defined in Chaco: :ref:`axes `, :ref:`legends `, and :ref:`grids `. @@ -154,3 +157,46 @@ Legend Grid ==== + +=================== +Annotation Overlays +=================== + +PointMarker +=========== + +DataBox +======= + +.. _tools/text_box_overlay: + +TextBoxOverlay +============== +The :class:`chaco.overlays.api.TextBoxOverlay` is the base class of +the overlay component of several inspector type tools (see above). It is +designed to draw a text box over the plots to display custom information. + +The rendering of the text can be customized with the following attributes: + + * :attr:`bgcolor` and :attr:`border_visible` to control the styling of the + box, + * :attr:`alpha` to control the transparency of the text box, + * :attr:`text_color` and :attr:`font` to control how the text looks like, + * :attr:`align` to control what corner of the plot the text box should + appear, + * ... + +.. note:: The overlay can also be used directly by any custom tool that needs + to display information upon an event. It should be done by + subclassing the overlay and defining a listener on the inspector's + state which will modify the overlay's :attr:`text` (and optionally + visibility) attribute(s). After a `text` update, the component's + :meth:`request_redraw` should be called. Good examples include + :class:`chaco.overlays.api.ImageInspectorOverlay`. + + +ToolTip +======= + +PlotLabel +========= diff --git a/docs/source/user_manual/tools.rst b/docs/source/user_manual/basic_elements/tools.rst similarity index 71% rename from docs/source/user_manual/tools.rst rename to docs/source/user_manual/basic_elements/tools.rst index 89b453168..edc0ad356 100644 --- a/docs/source/user_manual/tools.rst +++ b/docs/source/user_manual/basic_elements/tools.rst @@ -1,6 +1,6 @@ -****************** -Tools and Overlays -****************** +***** +Tools +***** ================================================================ Overview @@ -151,66 +151,3 @@ DrawPointsTool LineSegmentTool =============== - - -================================================================ -Core Overlays -================================================================ - -Axis -==== - -Grid -==== - -Legend -====== - - -================================================================ -Annotation Overlays -================================================================ - -PointMarker -=========== - -DataBox -======= - - -.. _tools/text_box_overlay: - -TextBoxOverlay -============== -The :class:`chaco.overlays.api.TextBoxOverlay` is the base class of -the overlay component of several inspector type tools (see above). It is -designed to draw a text box over the plots to display custom information. - -The rendering of the text can be customized with the following attributes: - - * :attr:`bgcolor` and :attr:`border_visible` to control the styling of the - box, - * :attr:`alpha` to control the transparency of the text box, - * :attr:`text_color` and :attr:`font` to control how the text looks like, - * :attr:`align` to control what corner of the plot the text box should - appear, - * ... - -.. note:: The overlay can also be used directly by any custom tool that needs - to display information upon an event. It should be done by - subclassing the overlay and defining a listener on the inspector's - state which will modify the overlay's :attr:`text` (and optionally - visibility) attribute(s). After a `text` update, the component's - :meth:`request_redraw` should be called. Good examples include - :class:`chaco.overlays.api.ImageInspectorOverlay`. - - -ToolTip -======= - -PlotLabel -========= - - - - diff --git a/docs/source/user_manual/chaco_tutorial.rst b/docs/source/user_manual/chaco_tutorial.rst index e6331fe9f..b0f019542 100644 --- a/docs/source/user_manual/chaco_tutorial.rst +++ b/docs/source/user_manual/chaco_tutorial.rst @@ -1,3 +1,4 @@ +:orphan: .. highlight:: python :linenothreshold: 10 @@ -1247,8 +1248,13 @@ they are constructed: almost all tools need to use some capabilities Final words =========== -This concludes this tutorial. For further information, please refer -to the :ref:`Resources` page, or visit the :ref:`user_guide`. +This concludes this tutorial. You can download :download:`a PDF version of the slides <../resources/scipy08_tutorial.pdf>` +For further information, visit the :ref:`user_guide`. You can find the examples +for this tutorial in the :file:`examples/tutorials/scipy2008/` directory of the +Chaco source code. You can browse it online in the `GitHub repository `_ +if you don't have a local copy. They are numbered and introduce concepts one at +a time, going from a simple line plot to building a custom overlay with its own +trait editor and reusing an existing tool from the built-in set of tools. *This tutorial is based on the "Interactive plotting with Chaco" tutorial diff --git a/docs/source/user_manual/containers.rst b/docs/source/user_manual/containers.rst index 868862449..7d0b1f06b 100644 --- a/docs/source/user_manual/containers.rst +++ b/docs/source/user_manual/containers.rst @@ -1,5 +1,3 @@ -.. highlight:: python - :linenothreshold: 10 ********************* Containers and Layout @@ -21,7 +19,7 @@ All containers are derived from the base class :class:`~chaco.base_plot_container.​BasePlotContainer`, and share a common interface: -* ``__init__(*components, **parameters)`` (constructor of the container object): +:py:meth:`__init__`: The constructor of a plot container takes a sequence of components, which are added to the container itself, and a set of keyword arguments, which are used to initialize the @@ -33,45 +31,43 @@ a common interface: (``scatter_plot`` and ``line_plot``), with a spacing of 100 pixels between them. -* ``add(*components)``: Append ore or more plots to the ones already present in the +:py:meth:`add`: + Append one or more plots to the ones already present in the container. For example, this is equivalent to the code above:: container = HPlotContainer(spacing=100) container.add(line_plot, scatter_plot) -* ``remove(self, *components)``: Remove a sequence of components from the - container +:py:meth:`remove`: + Remove a sequence of components from the container -* ``insert(index, component)``: Inserts a component at a specific position - in the components list +:py:meth:`insert`: + Inserts a component at a specific position in the components list -.. note:: - - **Each plot can have only one container**, so adding the same plot to - a second container will remove it from the first one. In the same way, - adding the same plot multiple times will not have create multiple - copies. Instead, one should create multiple plots objects. - - E.g., this code:: +**Each plot can have only one container**, so adding the same plot to +a second container will remove it from the first one. In the same way, +adding the same plot multiple times will not have create multiple +copies. Instead, one should create multiple plots objects. - # Create a vertical container containing two horizontal containers - h_container1 = HPlotContainer() - h_container2 = HPlotContainer() - outer_container = VPlotContainer(h_container1, h_container2, - stack_order="top_to_bottom") +E.g., this code:: - # Add the three plots to the first container - h_container1.add(scatter_plot, line_plot1, line_plot2) + # Create a vertical container containing two horizontal containers + h_container1 = HPlotContainer() + h_container2 = HPlotContainer() + outer_container = VPlotContainer(h_container1, h_container2, + stack_order="top_to_bottom") - # Now add the first line plot to the second container => it is removed - # from the first, as each plot can only have one container - h_container2.add(line_plot1) + # Add the three plots to the first container + h_container1.add(scatter_plot, line_plot1, line_plot2) - results in this layout: + # Now add the first line plot to the second container => it is removed + # from the first, as each plot can only have one container + h_container2.add(line_plot1) - .. image:: images/user_guide/one_container_per_plot.png - :height: 200pt +results in this layout: + .. image:: images/user_guide/one_container_per_plot.png + :height: 200pt .. _hv-plot-container: @@ -149,18 +145,18 @@ HPlotContainer parameters This is a list of parameters that are specific to :class:`~chaco.plot_containers.HPlotContainer` -* ``stack_order``: +:py:attr:`stack_order`: The order in which components in the plot container are laid out. The default behavior is left-to-right. :: stack_order = Enum("left_to_right", "right_to_left") -* ``spacing``: +:py:attr:`spacing`: The amount of space to put between components. :: spacing = Float(0.0) -* ``valign``: +:py:attr:`valign`: The vertical alignment of objects that don't span the full height. :: valign = Enum("bottom", "top", "center") @@ -172,18 +168,18 @@ VPlotContainer parameters This is a list of parameters that are specific to :class:`~chaco.plot_containers.VPlotContainer` -* ``stack_order``: +:py:attr:`stack_order`: The order in which components in the plot container are laid out. The default behavior is bottom-to-top. :: stack_order = Enum("bottom_to_top", "top_to_bottom") -* ``spacing``: +:py:attr:`spacing`: The amount of space to put between components.:: spacing = Float(0.0) -* ``halign``: +:py:attr:`halign`: The horizontal alignment of objects that don't span the full width.:: halign = Enum("left", "right", "center") @@ -270,18 +266,19 @@ GridPlotContainer parameters This is a list of parameters that are specific to :class:`~chaco.plot_containers.GridPlotContainer` -* ``valign``: +:py:attr:`valign`: The vertical alignment of objects that don't span the full height.:: valign = Enum("bottom", "top", "center") -* ``halign``: +:py:attr:`halign`: The horizontal alignment of objects that don't span the full width.:: halign = Enum("left", "right", "center") -* ``spacing``: A tuple or list of ``(h_spacing, v_spacing)``, +:py:attr:`spacing`: + A tuple or list of ``(h_spacing, v_spacing)``, giving spacing values for the horizontal and vertical direction. Default is (0, 0). @@ -379,22 +376,26 @@ their container to set their final aspect. The basic traits that control the layout preferences of a component are: -* :attr:`resizable`, a string indicating in which directions the component +:attr:`resizable`: + A string indicating in which directions the component can be resized. Its value is one of ``''`` (not resizable), ``'h'`` (resizable in the horizontal direction), ``'v'`` (resizable in the vertical direction), ``'hv'`` (resizable in both, default). -* :attr:`aspect_ratio`, the ratio of the component's width to its height. +:attr:`aspect_ratio`: + The ratio of the component's width to its height. This is used by the component itself to maintain bounds when the bounds are changed independently. Default is ``None``, meaning that the aspect ratio is not enforced. -* :attr:`padding_left`, :attr:`padding_right`, - :attr:`padding_top`, :attr:`padding_bottom` set the amount of padding space +:attr:`padding_left`, :attr:`padding_right`, :attr:`padding_top`, :attr:`padding_bottom`: + Set the amount of padding space to leave around the component (default is 0). The property :attr:`padding` allows to set all of them as a tuple (left, right, top, bottom). -* :attr:`auto_center`, controls the behavior when the component's bounds are +:attr:`auto_center`: + Controls the behavior when the component's bounds are set to a value that does not conform its aspect ratio. If ``True`` (default), the component centers itself in the free space. -* :attr:`fixed_preferred_size`: If the component is resizable, this attribute +:attr:`fixed_preferred_size`: + If the component is resizable, this attribute specifies the amount of space that the component would like to get in each dimension, as a tuple (width, height). This attribute can be used to establish @@ -403,18 +404,17 @@ The basic traits that control the layout preferences of a component are: specifies a fixed preferred width of 100, then the latter component will always be twice as wide as the former. -You can get access to the actual bounds of the component, (including -padding and border) using the -``outer`` properties: +You can get access to the actual bounds of the component, (including padding and border) +using the ``outer`` properties: -* :attr:`outer_position`, the x,y point of the lower left corner of the +:attr:`outer_position`: + The x,y point of the lower left corner of the padding outer box around the component. Use :meth:`set_outer_position` to change these values. -* :attr:`outer_bounds`, - the number of horizontal and vertical pixels in the padding outer box. +:attr:`outer_bounds`: + The number of horizontal and vertical pixels in the padding outer box. Use :meth:`set_outer_bounds` to change these values. -* :attr:`outer_x`, :attr:`outer_y`, :attr:`outer_x2`, :attr:`outer_y2:, - :attr:`outer_width`, :attr:`outer_height`: +:attr:`outer_x`, :attr:`outer_y`, :attr:`outer_x2`, :attr:`outer_y2:, :attr:`outer_width`, :attr:`outer_height`: coordinates of lower-left pixel of the box, coordinates of the upper-right pixel of the box, width and height of the outer box in pixels diff --git a/docs/source/user_manual/how_do_i.rst b/docs/source/user_manual/how_do_i.rst index 88317820f..6639be9d5 100644 --- a/docs/source/user_manual/how_do_i.rst +++ b/docs/source/user_manual/how_do_i.rst @@ -1,3 +1,5 @@ +.. _how_do_i: + ############ How Do I...? ############ @@ -5,13 +7,14 @@ How Do I...? .. note:: This section is currently under active development. + +.. contents:: Basics ====== -*How do I...* - -* render data to an image file? +Render data to an image file? +----------------------------- :: @@ -22,7 +25,8 @@ Basics gc.render_component(plot) gc.save(filename) -* integrate a Chaco plot into my WX app? +Integrate a Chaco plot into my WX app? +-------------------------------------- :: @@ -33,36 +37,46 @@ Basics from enable.api import Window class PlotFrame(wx.Frame): - def __init__(self, *args, **kw): - kw["size"] = (850, 550) - wx.Frame.__init__( *(self,) + args, **kw ) - self.plot_window = Window(self, component=self._create_plot()) - sizer = wx.BoxSizer(wx.HORIZONTAL) - sizer.Add(self.plot_window.control, 1, wx.EXPAND) - self.SetSizer(sizer) - self.SetAutoLayout(True) - self.Show(True) - return - - def _create_plot(self): - x = arange(-5.0, 15.0, 20.0/100) - y = jn(0, x) - plot = create_line_plot((x,y), bgcolor="white", - add_grid=True, add_axis=True) - container = HPlotContainer(spacing=20, padding=50, bgcolor="lightgray") - container.add(plot) - return container + + def __init__(self, *args, **kw): + kw["size"] = (850, 550) + super(PlotFrame, self).__init__(*args, **kw) + self.plot_window = Window(self, component=self._create_plot()) + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.plot_window.control, 1, wx.EXPAND) + self.SetSizer(sizer) + self.SetAutoLayout(True) + self.Show(True) + + def _create_plot(self): + x = arange(-5.0, 15.0, 20.0/100) + y = jn(0, x) + plot = create_line_plot( + (x,y), + bgcolor="white", + add_grid=True, + add_axis=True, + ) + container = HPlotContainer( + spacing=20, + padding=50, + bgcolor="lightgray", + ) + container.add(plot) + return container if __name__ == "__main__": - app = wx.PySimpleApp() - frame = PlotFrame(None) - app.MainLoop() + app = wx.PySimpleApp() + frame = PlotFrame(None) + app.MainLoop() Note that this will require for the ETS_TOOLKIT environment variable to be set to 'wx'. * integrate a Chaco plot into my QT app? -* integrate a Chaco plot into my Traits UI? + +Integrate a Chaco plot into my Traits UI? +----------------------------------------- :: @@ -75,7 +89,7 @@ be set to 'wx'. class MyPlot(HasTraits): plot = Instance(Plot) - traits_view = View(Item('plot', editor=ComponentEditor())) + traits_view = View(Item('plot', editor=ComponentEditor())) def __init__(self, index, data_series, **kw): super(MyPlot, self).__init__(**kw) @@ -92,7 +106,8 @@ be set to 'wx'. my_plot.configure_traits() -* make an application to render many streams of data? +Make an application to render many streams of data? +--------------------------------------------------- :: @@ -105,19 +120,21 @@ be set to 'wx'. plot_data.set_data(series_name, data_series) plot.plot(('index', series_name)) -* make a plot the right size? +Make a plot the right size? +--------------------------- :: def resize_plot(plot, width, height): plot.outer_bounds = [width, height] -* copy a plot the the clipboard? +Copy a plot the the clipboard? +------------------------------ :: def copy_to_clipboard(plot): - # WX specific, though QT implementation is similar using + # WX specific, though QT implementation is similar using # QImage and QClipboard import wx @@ -126,10 +143,10 @@ be set to 'wx'. gc = PlotGraphicsContext((width, height), dpi=72) gc.render_component(plot_component) - # Create a bitmap the same size as the plot + # Create a bitmap the same size as the plot # and copy the plot data to it - bitmap = wx.BitmapFromBufferRGBA(width+1, height+1, + bitmap = wx.BitmapFromBufferRGBA(width+1, height+1, gc.bmp_array.flatten()) data = wx.BitmapDataObject() data.SetBitmap(bitmap) @@ -147,7 +164,9 @@ Layout and Rendering *How do I...* * put multiple plots in a single window? -* change the background color? + +Change the background color? +---------------------------- :: @@ -160,7 +179,8 @@ Layout and Rendering def change_bgcolor(plot): plot.bgcolor = 'black' -* turn off borders? +Turn off borders? +----------------- :: @@ -183,7 +203,7 @@ Writing Components * write a custom renderer? * write a custom overlay/underlay? * write a custom tool? -* write a new container? +* write a new container? Advanced @@ -194,5 +214,5 @@ Advanced * properly change/override draw dispatch? * modify event dispatch? * customize backbuffering? -* embed custom/native WX widgets on the plot? +* embed custom/native WX widgets on the plot? diff --git a/docs/source/user_manual/images/power_function_example.png b/docs/source/user_manual/images/power_function_example.png new file mode 100644 index 000000000..d98a66cb1 Binary files /dev/null and b/docs/source/user_manual/images/power_function_example.png differ diff --git a/docs/source/user_manual/index.rst b/docs/source/user_manual/index.rst index 36ad5bd2d..7931596d0 100644 --- a/docs/source/user_manual/index.rst +++ b/docs/source/user_manual/index.rst @@ -1,16 +1,29 @@ +:orphan: + .. _user_guide: + =========== -User guide +User Guide =========== .. toctree:: - :maxdepth: 3 + :maxdepth: 2 introduction.rst - plot_types.rst + installation.rst + quickstart.rst + modules_and_classes + plots.rst containers.rst - tools.rst + + basic_elements/data_sources.rst + basic_elements/data_ranges.rst + basic_elements/mappers.rst + basic_elements/plot_renderers.rst + basic_elements/tools.rst + basic_elements/overlays.rst + plot_types.rst common_patterns.rst how_do_i.rst faq.rst diff --git a/docs/source/user_manual/installation.rst b/docs/source/user_manual/installation.rst new file mode 100644 index 000000000..cafed750a --- /dev/null +++ b/docs/source/user_manual/installation.rst @@ -0,0 +1,150 @@ +.. _installation: + +============ +Installation +============ + +There are several ways to get Chaco. The easiest way is through `Enthought +Deployment Manager `_ (formerly EPD) +which provides environment management and package installation tools for +Windows, Linux and MacOS. Chaco may also be available through a package manager +on your platform, such as apt on Ubuntu, yum on Redhat or +`MacPorts `_ on OS X. You can also build Chaco from +its `source code `_, but because of the +dependencies, the easiest way by far is to install EDM. + +.. _dependencies: + +Dependencies +============ + +* `Python `_ 2.7 or 3.5+ + +* `Traits `_, an event notification + framework + +* `TraitsUI `_, a rapid GUI application + development framework + +* `Kiva `_, part of the enable project, + for rendering 2-D graphics to a variety of backends across platforms + +* `Enable `_, a framework for writing + interactive visual components, and for abstracting away GUI-toolkit-specific + details of mouse and keyboard handling. + +* `NumPy `_, for dealing efficiently with large + datasets + +* Either `wxPython `_, `PyQt + `_ (GPL or + Commercial license) or `PySide `_ (LGPL license) to + display interactive plots. + +* (optionally) `ReportLab `_ + for PDF and PostScript output, and `Pillow `_ + for raster image output. + +Installing Chaco with EDM +========================= + +To install via EDM, `download EDM +`_ +for your platform and then do (from the command line) + +.. code-block:: console + + edm install chaco pyqt5 + +to install Chaco, PyQt, and their dependencies and then + +.. code-block:: console + + edm shell + +to enter the Python environment with these packages installed. + +PyQt5 is one of multiple supported backends. Other options include PyQt, +Pyside2, or wxPython. + +Installing Chaco from Source +============================ + +If you choose to build Chaco rather than installing from a package manager +you will need a build environment that includes the standard C/C++ compiler +for your platform and Python version (see the Python documentation for more +information). If you are going to build the dependencies you will also need +to install SWIG and you may want to install Cython if you want to update the +extension modules in Chaco. + +Installation via Pip +-------------------- + +Chaco itself uses standard Python packaging via a setup.py script, so once +you have your build environment set up, you can install using Pip as you would +any other Python package. + +.. code-block:: console + + $ pip install chaco + +This will download the source distribution from PyPI and automatically build +Chaco and its dependencies for you. + +.. note:: + If you have already installed Chaco and just want to update to the newest + version, use + + .. code-block:: console + + $ pip install --upgrade chaco + +Installation via setup.py +------------------------- + +Alternatively, you can download the source code from the `Chaco GitHub +repository `_ and use the standard +`setup.py` installation commands: + +.. code-block:: console + + $ python setup.py install + +This will attempt to install and build all dependencies as part of the +installation process. + +Developer Live Installation +--------------------------- + +It is also possible to install a live-editable source installation +using + +.. code-block:: console + + $ pip install -e . + +at the top level of the Chaco source code. + +Extension Modules +================= + +Chaco contains a number of C extension modules used mainly for speed. In the +current version of Chaco, the following extension modules are currently used: + +``chaco/_cython_speedups.pyx`` + This is a Cython extension which speeds up a number of standard operations, + currently mainly involving color maps. If this is not available, Chaco will + fall back on slower NumPy-based algorithms. + +``chaco/contour/_cntr.c`` + Contour tracing on quadrilateral meshes. This is required for contour plots. + +``chaco/downsample/_lttb.pyx`` + Implementation of the "largest triangle three buckets" downsampling algorithm + for line plots. If this is not available, then "lttb" downsampling of line + plots will fail. + +The Chaco source code includes the generated ``*.c`` files for each of the Cython +``*.pyx`` files, so Cython is not required to build Chaco. It is needed, however +if you are going to make changes to the Cython extension modules. + diff --git a/docs/source/user_manual/introduction.rst b/docs/source/user_manual/introduction.rst index 570fcb430..0849b9307 100644 --- a/docs/source/user_manual/introduction.rst +++ b/docs/source/user_manual/introduction.rst @@ -2,6 +2,14 @@ Introduction ************ +This guide is designed to act as a conceptual guide to Chaco, an open-source +data visualization library built and maintained by Enthought, Inc. Chaco is +a set of interactive visualization tools built on top of the Enable and Kiva +2D drawing libraries and designed to complement other Enthought rapid +application development tools including Traits and TraitsUI. This guide +discusses many, but not all of the features of Chaco. For complete details +of the Chaco API, refer to the Chaco API documentation. + ============== What is Chaco? ============== @@ -11,7 +19,7 @@ the Enthought Tools Suite. The strong points of Chaco are -1. it can be :ref:`embedded ` in any wx, Qt, or TraitsUI application +1. it can be :ref:`embedded ` in any Wx, Qt, or TraitsUI application 2. it is designed for building interactive plotting applications, rather than static 2D plots @@ -19,7 +27,6 @@ The strong points of Chaco are 3. Chaco classes can be easily extended to create new plot types, interactive tools, and plot containers - At the lowest level, Chaco is a hierarchy of classes that defines 2D plotting elements: plots, containers, interactive tools, color bars, etc. In principle, applications can create instances of these elements and lay them @@ -28,21 +35,20 @@ of several of graphical back ends `. Working at this level allows the maximum flexibility, but requires understanding :ref:`Chaco's basic elements `. -Chaco defines two abstraction layers that allow a more high-level -(albeit less flexible) plotting experience. First, Chaco contains a -:class:`~chaco.plot.Plot` -class that defines several methods that create a complete plot given one or -more data sets. In other words, :class:`~chaco.plot.Plot` knows how to -package data for the most common kinds of plots. Second, Chaco has a -:mod:`shell` module that defines high-level plotting functions. This module -allows using Chaco as an interactive plotting tool that will be familiar -to users of matplotlib. +Chaco defines two abstraction layers that allow a more high-level (albeit +less flexible) plotting experience. First, Chaco contains a +:class:`~chaco.plot.Plot` class that defines several methods that create a +complete plot given one or more data sets. In other words, +:class:`~chaco.plot.Plot` knows how to package data for the most common kinds +of plots. Second, Chaco has a :mod:`shell` module that defines high-level +plotting functions. This module allows using Chaco as an interactive plotting +tool that will be familiar to users of matplotlib. .. _basic_elements: -============== -Basic elements -============== +========== +Core Ideas +========== To venture deeper in Chaco's architecture it is useful to understand a few basic ideas on which Chaco is based: @@ -75,6 +81,20 @@ basic ideas on which Chaco is based: interactive tools that add graphical elements to a plot without having to modify the drawing logic. +* **Modular design and extensible classes** + + Chaco is meant to be used for writing tools and applications, and code + reuse and good class design are important. We use the math behind the + data and visualizations to give us architectural direction and conceptual + modularity. The Traits framework allows us to use events to couple + disjoint components at another level of modularity. + + Also, rather than building super-flexible core objects with myriad + configuration attributes, Chaco's classes are written with subclassing in + mind. While they are certainly configurable, the classes themselves are + written in a modular way so that subclasses can easily customize + particular aspects of a visual component's appearance or a tool's + behavior. These pages describe in detail the basic building blocks of Chaco plots, and the classes that implement them: @@ -86,67 +106,13 @@ Chaco plots, and the classes that implement them: basic_elements/data_ranges.rst basic_elements/mappers.rst basic_elements/plot_renderers.rst - plot_types.rst + basic_elements/tools.rst basic_elements/overlays.rst + plot_types.rst -TODO: find out how the selection features are organized - -TODO: to see how these elements collaborate to build an interactive plot, -give complete low-level example of line plot with simple tool and -describe the exchange of information - - -Tools -===== - - before axes (axes are overlays) - tools, overlays - - -=================== -Plotting with Chaco -=================== - -The Plot class -============== - -Plot and PlotData - -chaco.shell -=========== - -======================== -Low-level Chaco plotting -======================== - -1) create instances of PlotRenderer and add them to a Container. - There are factory functions in - plot_factory that make it simpler - -2) Create a Plot instance, use methods to create new plots of different kinds. - This automatizes 1) with an OverlayPlotContainer, i.e., it - plots multiple curves on the same element - -Plots can be rendered in a traitsui, wx, or qt window - - - - -.. _embedding: - -===================== -Embedding Chaco plots -===================== - -Traits UI -========= - -WxPython -======== - -Qt/PyQt -======= - - +.. comment: TODO: find out how the selection features are organized +.. comment: TODO: to see how these elements collaborate to build an interactive + plot, give complete low-level example of line plot with simple tool and + describe the exchange of information diff --git a/docs/source/user_manual/modules_and_classes.rst b/docs/source/user_manual/modules_and_classes.rst new file mode 100644 index 000000000..38d92a2c2 --- /dev/null +++ b/docs/source/user_manual/modules_and_classes.rst @@ -0,0 +1,255 @@ + +.. _modules_and_classes: + +Commonly Used Modules and Classes +================================= + +Base Classes +----------------------------------------------------------------------------- + +.. rubric:: Plot Component + +All visual components in Chaco subclass from +:class:`~chaco.plot_component.PlotComponent`. It defines all of the common +visual attributes like background color, border styles and color, and whether +the component is visible. (Actually, most of these visual attributes are +inherited from the Enable drawing framework.) More importantly, it provides the +base behaviors for participating in layout, handling event dispatch to tools +and overlays, and drawing various layers in the correct order. Subclasses +almost never need to override or customize these base behaviors, but if they +do, there are several easy extension points. + +PlotComponent is a subclass of Enable :class:`~enable.component.Component`. It +has its own default drawing order. It redefines the inherited traits +:attr:`draw_order` and :attr:`draw_layer`, but it doesn't define any new +traits. Therefore, you may need to refer to the API documentation for Enable +Component, even when you have subclassed Chaco PlotComponent. + +If you subclass PlotComponent, you need to implement :meth:`do_layout`, +if you want to size the component correctly. + + +Data Objects +----------------------------------------------------------------------------- + +.. rubric:: Data Source + +A data source is a wrapper object for the actual data that it will be +handling. It provides methods for retrieving data, estimating a size of the +dataset, indications about the dimensionality of the data, a place for metadata +(such as selections and annotations), and events that fire when the data gets +changed. There are two primary reasons for a data source class: + +* It provides a way for different plotting objects to reference the same data. +* It defines the interface for embedding Chaco into an existing application. + In most cases, the standard ArrayDataSource will suffice. + +*Interface:* :class:`~chaco.abstract_data_source.AbstractDataSource` + +*Subclasses:* :class:`~chaco.array_data_source.ArrayDataSource`, +:class:`~chaco.multi_array_data_source.MultiArrayDataSource`, +:class:`~chaco.point_data_source.PointDataSource`, +:class:`~chaco.grid_data_source.GridDataSource`, +:class:`~chaco.image_data.ImageData` + +.. rubric:: Data Range + +A data range expresses bounds on data space of some dimensionality. The simplest +data range is just a set of two scalars representing (low, high) bounds in 1-D. +One of the important aspects of data ranges is that their bounds can be set to +``auto``, which means that they automatically scale to fit their associated +datasources. (Each data source can be associated with multiple ranges, +and each data range can be associated with multiple data sources.) + +*Interface*: :class:`~chaco.abstract_data_range.AbstractDataRange` + +*Subclasses*: :class:`~chaco.base_data_range.BaseDataRange`, +:class:`~chaco.data_range_1d.DataRange1D`, +:class:`~chaco.data_range_2d.DataRange2D` + +.. rubric:: Data Source + +A data source is an object that supplies data to Chaco. For the most part, a +data source looks like an array of values, with an optional mask and metadata. + +*Interface*: :class:`~chaco.abstract_data_source.AbstractDataSource` + +*Subclasses*: :class:`~chaco.array_data_source.ArrayDataSource`, +:class:`~chaco.grid_data_source.GridDataSource`, +:class:`~chaco.image_data.ImageData`, +:class:`~chaco.multi_array_data_source.MultiArrayDataSource`, +:class:`~chaco.point_data_source.PointDataSource` + +The :attr:`metadata` trait attribute is a dictionary where you can stick +stuff for other tools to find, without inserting it in the actual data. + +Events that are fired on data sources are: + +* :attr:`data_changed` +* :attr:`bounds_changed` +* :attr:`metadata_changed` + + +.. rubric:: Mapper + +Mappers perform the job of mapping a data space region to screen space, and +vice versa. Bounds on mappers are set by data range objects. + +*Interface*: :class:`~chaco.abstract_mapper.AbstractMapper` + +*Subclasses*: :class:`~chaco.base_1d_mapper.Base1DMapper`, +:class:`~chaco.linear_mapper.LinearMapper`, +:class:`~chaco.log_mapper.LogMapper`, :class:`~chaco.grid_mapper.GridMapper`, +:class:`~chaco.polar_mapper.PolarMapper` + + +Containers +----------------------------------------------------------------------------- + +.. rubric:: PlotContainer + +:class:`~.PlotContainer` is Chaco's way of handling layout. Because it logically +partitions the screen space, it also serves as a way for efficient event +dispatch. It is very similar to sizers or layout grids in GUI toolkits like +WX. Containers are subclasses of PlotComponent, thus allowing them to +be nested. :class:`~.BasePlotContainer` implements the logic to correctly render +and dispatch events to sub-components, while its subclasses implement the +different layout calculations. + +A container gets the preferred size from its components, and tries to allocate +space for them. Non-resizeable components get their required size; whatever is +left over is divided among the resizeable components. + +Chaco currently has three types of containers, +described in the following sections. + +*Interface*: :class:`~.BasePlotContainer` + +*Subclasses*: :class:`~.OverlayPlotContainer`, :class:`~.HPlotContainer`, +:class:`~.VPlotContainer`, :class:`~.GridPlotContainer` + +The listed subclasses are defined in the module +:mod:`chaco.plot_containers`. + + +Renderers +----------------------------------------------------------------------------- + +Plot renderers are the classes that actually draw a type of plot. + +*Interface*: :class:`~.AbstractPlotRenderer` + +*Subclasses*: + +* :class:`~.BarPlot` +* :class:`~.Base2DPlot` + + * :class:`~.ContourLinePlot` + * :class:`~.ContourPolyPlot` + * :class:`~.ImagePlot`: displays an image file, or color-maps scalar + data to make an image + * :class:`~.CMapImagePlot` + +* :class:`~.BaseXYPlot`: This class is often emulated by writers of other + plot renderers, but renderers don't *need* to be structured this way. + By convention, many have a :meth:`hittest` method. They *do* need + to implement :meth:`map_screen`, :meth:`map_data`, and :meth:`map_index` + from :class:`~.AbstractPlotRenderer`. + + * :class:`~.LinePlot` + + * :class:`~.ErrorBarPlot` + + * :class:`~.PolygonPlot` + + * :class:`~.FilledLinePlot` + + * :class:`~.ScatterPlot` + + * :class:`~.ColormappedScatterPlot` + + * :class:`~.ColorBar` + * :class:`~.PolarLineRenderer`: NOTE: doesn't play well with others + +You can use these classes to compose more interesting plots. + +The module :mod:`chaco.plot_factory` contains various convenience +functions for creating plots, which simplify the set-up. + +The :class:`~chaco.plot.Plot` class (called "capital P Plot" when +speaking) represents what the user usually thinks of as a "plot": a set of data, +renderers, and axes in a single screen region. It is a subclass of +:class:`~.DataView`. + +Tools +----------------------------------------------------------------------------- + +Tools attach to a component, which gives events to the tool. + +All tools subclass from Enable's :py:class:`~enable.base_tool.BaseTool`, which +is in turn an Enable :py:class:`~enable.interactor.Interactor`. Do not try to +make tools that draw: use an overlay for that. + +Some tool subclasses exist in both Enable and Chaco, because they were created +first in Chaco, and then moved into Enable. + +*Interface*: :py:class:`~enable.base_tool.BaseTool` + +*Subclasses*: + +* :class:`~.BroadcasterTool`: Keeps a list of other tools, and broadcasts + events it receives to all those tools. +* :class:`~.DataPrinter`: Prints the data-space position of the point + under the cursor. +* :class:`enable.tools.drag_tool.DragTool`: Enable base class + for tools that do dragging. + + * :class:`~chaco.tools.move_tool.MoveTool` + * :class:`enable.tools.resize_tool.ResizeTool` + * :class:`enable.tools.viewport_pan_tool.ViewportPanTool` + +* :class:`~.chaco.tools.drag_tool.DragTool`: Chaco base class + for tools that do dragging. + + * :class:`~chaco.tools.cursor_tool.BaseCursorTool` + + * :class:`~chaco.tools.cursor_tool.CursorTool1D` + * :class:`~chaco.tools.cursor_tool.CursorTool2D` + + * :class:`~.DataLabelTool` + * :class:`~.DragZoom` + * :class:`~.LegendTool` + * :class:`~.MoveTool` + +* :class:`~.DrawPointsTool` +* :class:`~.HighlightTool` +* :class:`enable.tools.hover_tool.HoverTool` +* :class:`~.ImageInspectorTool` +* :class:`~.LineInspector` +* :class:`~.PanTool` + + * :class:`~.TrackingPanTool` + +* :class:`~.PointMarker` +* :class:`~.SaveTool` +* :class:`~.SelectTool` + + * :class:`~.ScatterInspector` + * :class:`~.SelectableLegend` + +* :class:`enable.tools.traits_tool.TraitsTool` + + * :class:`~chaco.tools.traits_tool.TraitsTool` + +DragTool is a base class for tools that do dragging. + +Other tools do things like panning, moving, highlighting, line segments, range selection, drag zoom, move data labels, scatter inspection, Traits UI. + +Overlays +----------------------------------------------------------------------------- + + +Miscellaneous +----------------------------------------------------------------------------- + + diff --git a/docs/source/user_manual/plot_types.rst b/docs/source/user_manual/plot_types.rst index 539294f7f..00102a695 100644 --- a/docs/source/user_manual/plot_types.rst +++ b/docs/source/user_manual/plot_types.rst @@ -41,33 +41,33 @@ Line Plot Standard line plot implementation. The aspect of the line is controlled by the parameters - :attr:`~chaco.lineplot.LinePlot.line_width` - The width of the line (default is 1.0) +:attr:`~chaco.lineplot.LinePlot.line_width` + The width of the line (default is 1.0) - :attr:`~chaco.lineplot.LinePlot.line_style` - The style of the line, one of 'solid' (default), 'dot dash', 'dash', 'dot', - or 'long dash'. +:attr:`~chaco.lineplot.LinePlot.line_style` + The style of the line, one of 'solid' (default), 'dot dash', 'dash', 'dot', + or 'long dash'. - :attr:`~chaco.lineplot.LinePlot.render_style` - The rendering style of the line plot, one of - 'connectedpoints' (default), 'hold', or 'connectedhold' +:attr:`~chaco.lineplot.LinePlot.render_style` + The rendering style of the line plot, one of + 'connectedpoints' (default), 'hold', or 'connectedhold' These images illustrate the differences in rendering style: * ``renderstyle='connectedpoints'`` - .. image:: images/user_guide/line_plot.png - :width: 500px +.. image:: images/user_guide/line_plot.png + :width: 500px * ``renderstyle='hold'`` - .. image:: images/user_guide/line_hold_plot.png - :width: 500px +.. image:: images/user_guide/line_hold_plot.png + :width: 500px * ``renderstyle='connectedhold'`` - .. image:: images/user_guide/line_connectedhold_plot.png - :width: 500px +.. image:: images/user_guide/line_connectedhold_plot.png + :width: 500px .. _scatter_plot: @@ -78,28 +78,28 @@ Scatter Plot Standard scatter plot implementation. The aspect of the markers is controlled by the parameters - :attr:`~chaco.scatterplot.ScatterPlot.marker` - The marker type, one of 'square'(default), 'circle', 'triangle', - 'inverted_triangle', 'plus', 'cross', 'diamond', 'dot', or 'pixel'. - One can also define a new marker shape by setting this parameter to 'custom', - and set the :attr:`~chaco.scatterplot.custom_symbol` parameter to - a :class:`CompiledPath` instance (see the file - ``demo/basic/scatter_custom_marker.py`` in the Chaco examples directory). +:attr:`~chaco.scatterplot.ScatterPlot.marker` + The marker type, one of 'square'(default), 'circle', 'triangle', + 'inverted_triangle', 'plus', 'cross', 'diamond', 'dot', or 'pixel'. + One can also define a new marker shape by setting this parameter to 'custom', + and set the :attr:`~chaco.scatterplot.custom_symbol` parameter to + a :class:`CompiledPath` instance (see the file + ``demo/basic/scatter_custom_marker.py`` in the Chaco examples directory). - :attr:`~chaco.scatterplot.ScatterPlot.marker_size` - Size of the marker in pixels, not including the outline. This can be - either a scalar (default is 4.0), or an array with one size per data - point. +:attr:`~chaco.scatterplot.ScatterPlot.marker_size` + Size of the marker in pixels, not including the outline. This can be + either a scalar (default is 4.0), or an array with one size per data + point. - :attr:`~chaco.scatterplot.ScatterPlot.line_width` - Width of the outline around the markers (default is 1.0). If this is 0.0, - no outline is drawn. +:attr:`~chaco.scatterplot.ScatterPlot.line_width` + Width of the outline around the markers (default is 1.0). If this is 0.0, + no outline is drawn. - :attr:`~chaco.scatterplot.ScatterPlot.color` - The fill color of the marker (default is black). +:attr:`~chaco.scatterplot.ScatterPlot.color` + The fill color of the marker (default is black). - :attr:`~chaco.scatterplot.ScatterPlot.outline_color` - The color of the outline to draw around the marker (default is black). +:attr:`~chaco.scatterplot.ScatterPlot.outline_color` + The color of the outline to draw around the marker (default is black). This is an example with fixed point size: @@ -129,24 +129,24 @@ In addition to the parameters supported by a :ref:`scatter plot `, a colormapped scatter plot defines these attributes: - :attr:`~chaco.colormapped_scatterplot.ColormappedScatterPlot.fill_alpha` - Set the alpha value of the points. +:attr:`~chaco.colormapped_scatterplot.ColormappedScatterPlot.fill_alpha` + Set the alpha value of the points. - :attr:`~chaco.colormapped_scatterplot.ColormappedScatterPlot.render_method` - Set the sequence in which the points are drawn. It is one of +:attr:`~chaco.colormapped_scatterplot.ColormappedScatterPlot.render_method` + Set the sequence in which the points are drawn. It is one of - 'banded' - draw points by color band; this is more efficient but some colors - will appear more prominently if there are a lot of overlapping points + 'banded' + draw points by color band; this is more efficient but some colors + will appear more prominently if there are a lot of overlapping points - 'bruteforce' - set the stroke color before drawing each marker + 'bruteforce' + set the stroke color before drawing each marker - 'auto' (default) - the approach is selected based on the number of points + 'auto' (default) + the approach is selected based on the number of points - In practice, there is not much performance difference between the two - methods. + In practice, there is not much performance difference between the two + methods. In this example plot, color represents nitric oxides concentration (green is low, red is high): @@ -173,40 +173,40 @@ and two stems (usually indicating the maximum and minimum values). The positions of the centers, and of the extrema of the bar and stems are set with the following data sources - :attr:`~chaco.candle_plot.CandlePlot.center_values` - Value of the centers. It can be set to ``None``, in which case the center is - not plotted. +:attr:`~chaco.candle_plot.CandlePlot.center_values` + Value of the centers. It can be set to ``None``, in which case the center is + not plotted. - :attr:`~chaco.candle_plot.CandlePlot.bar_min` and :attr:`~chaco.candle_plot.CandlePlot.bar_max` - Lower and upper values of the bar. +:attr:`~chaco.candle_plot.CandlePlot.bar_min` and :attr:`~chaco.candle_plot.CandlePlot.bar_max` + Lower and upper values of the bar. - :attr:`~chaco.candle_plot.CandlePlot.min_values` and :attr:`~chaco.candle_plot.CandlePlot.max_values` - Lower and upper values of the stem. They can be set to ``None``, in - which case the stems are not plotted. +:attr:`~chaco.candle_plot.CandlePlot.min_values` and :attr:`~chaco.candle_plot.CandlePlot.max_values` + Lower and upper values of the stem. They can be set to ``None``, in + which case the stems are not plotted. It is possible to customize the appearance of the candle plot with these parameters - :attr:`~chaco.candle_plot.CandlePlot.bar_color` (alias of :attr:`~chaco.candle_plot.CandlePlot.color`) - Fill color of the bar (default is black). +:attr:`~chaco.candle_plot.CandlePlot.bar_color` (alias of :attr:`~chaco.candle_plot.CandlePlot.color`) + Fill color of the bar (default is black). - :attr:`~chaco.candle_plot.CandlePlot.bar_line_color` (alias of :attr:`~chaco.candle_plot.CandlePlot.outline_color`) - Color of the box forming the bar (default is black). +:attr:`~chaco.candle_plot.CandlePlot.bar_line_color` (alias of :attr:`~chaco.candle_plot.CandlePlot.outline_color`) + Color of the box forming the bar (default is black). - :attr:`~chaco.candle_plot.CandlePlot.center_color` - Color of the line indicating the center. If ``None``, it defaults to - :attr:`~chaco.candle_plot.CandlePlot.bar_line_color`. +:attr:`~chaco.candle_plot.CandlePlot.center_color` + Color of the line indicating the center. If ``None``, it defaults to + :attr:`~chaco.candle_plot.CandlePlot.bar_line_color`. - :attr:`~chaco.candle_plot.CandlePlot.stem_color` - Color of the stems and endcaps. If ``None``, it defaults to - :attr:`~chaco.candle_plot.CandlePlot.bar_line_color`. +:attr:`~chaco.candle_plot.CandlePlot.stem_color` + Color of the stems and endcaps. If ``None``, it defaults to + :attr:`~chaco.candle_plot.CandlePlot.bar_line_color`. - :attr:`~chaco.candle_plot.CandlePlot.line_width`, :attr:`~chaco.candle_plot.CandlePlot.center_width`, and :attr:`~chaco.candle_plot.CandlePlot.stem_width` - Thickness in pixels of the lines drawing the corresponding elements. - If ``None``, they default to :attr:`~chaco.candle_plot.CandlePlot.line_width`. +:attr:`~chaco.candle_plot.CandlePlot.line_width`, :attr:`~chaco.candle_plot.CandlePlot.center_width`, and :attr:`~chaco.candle_plot.CandlePlot.stem_width` + Thickness in pixels of the lines drawing the corresponding elements. + If ``None``, they default to :attr:`~chaco.candle_plot.CandlePlot.line_width`. - :attr:`~chaco.candle_plot.CandlePlot.end_cap` - If ``False``, the end caps are not plotted (default is ``True``). +:attr:`~chaco.candle_plot.CandlePlot.end_cap` + If ``False``, the end caps are not plotted (default is ``True``). At the moment, it is not possible to control the width of the central bar @@ -232,11 +232,11 @@ In addition to the parameters supported by a :ref:`line plot `, an errorbar plot defines these attributes: - :attr:`~chaco.errorbar_plot.endcap_size` - The width of the endcap bars in pixels. +:attr:`~chaco.errorbar_plot.endcap_size` + The width of the endcap bars in pixels. - :attr:`~chaco.errorbar_plot.endcap_style` - Either 'bar' (default) or 'none', in which case no endcap bars are plotted. +:attr:`~chaco.errorbar_plot.endcap_style` + Either 'bar' (default) or 'none', in which case no endcap bars are plotted. .. image:: images/user_guide/errorbar_plot.png :width: 500px @@ -250,18 +250,18 @@ A line plot filled with color to the axis. :class:`~chacho.filled_line_plot.FilledLinePlot` defines the following parameters: - :attr:`~chaco.filled_line_plot.FilledLinePlot.fill_color` - The color used to fill the plot. +:attr:`~chaco.filled_line_plot.FilledLinePlot.fill_color` + The color used to fill the plot. - :attr:`~chaco.filled_line_plot.FilledLinePlot.fill_direction` - Fill the plot toward the origin ('down', default) ot towards the axis - maximum ('up'). +:attr:`~chaco.filled_line_plot.FilledLinePlot.fill_direction` + Fill the plot toward the origin ('down', default) ot towards the axis + maximum ('up'). - :attr:`~chaco.lineplot.LinePlot.render_style` - The rendering style of the line plot, one of - 'connectedpoints' (default), 'hold', or 'connectedhold' (see - :ref:`line plot ` for a description of the different - rendering styles). +:attr:`~chaco.lineplot.LinePlot.render_style` + The rendering style of the line plot, one of + 'connectedpoints' (default), 'hold', or 'connectedhold' (see + :ref:`line plot ` for a description of the different + rendering styles). :attr:`~chaco.filled_line_plot.FilledLinePlot` is a subclass of :attr:`~chaco.filled_line_plot.PolygonPlot`, so to set the thickness of the @@ -286,66 +286,53 @@ crossing each other. The relative displacement and rescaling of the lines is controlled by these attributes of :class:`~chaco.multi_line_plot.MultiLinePlot`: - :attr:`~chaco.multi_line_plot.MultiLinePlot.index` - - The usual array data source for the index data. - - :attr:`~chaco.multi_line_plot.MultiLinePlot.yindex` +:attr:`~chaco.multi_line_plot.MultiLinePlot.index` + The usual array data source for the index data. - Array data source for the starting point of each line. Typically, this - is set to ``numpy.arange(n_lines)``, so that each line is displaced - by one unit from the others (the other default parameters are set to - work well with this arrangement). +:attr:`~chaco.multi_line_plot.MultiLinePlot.yindex` + Array data source for the starting point of each line. Typically, this + is set to ``numpy.arange(n_lines)``, so that each line is displaced + by one unit from the others (the other default parameters are set to + work well with this arrangement). - :attr:`~chaco.multi_line_plot.MultiLinePlot.use_global_bounds`, - :attr:`~chaco.multi_line_plot.MultiLinePlot.global_min`, - :attr:`~chaco.multi_line_plot.MultiLinePlot.global_max`, +:attr:`~chaco.multi_line_plot.MultiLinePlot.use_global_bounds`, :attr:`~chaco.multi_line_plot.MultiLinePlot.global_min`, :attr:`~chaco.multi_line_plot.MultiLinePlot.global_max`, + These attributes are used to compute an "amplitude scale" which that + the largest trace deviation from its base y-coordinate will be equal + to the y-coordinate spacing. - These attributes are used to compute an "amplitude scale" which that - the largest trace deviation from its base y-coordinate will be equal - to the y-coordinate spacing. + If :attr:`use_global_bounds` is set to False, the maximum of the + absolute value of the full data is used as the largest trace deviation. + Otherwise, the largest between the absolute value of :attr:`global_min` + and :attr:`global_max` is used instead. - If :attr:`use_global_bounds` is set to False, the maximum of the - absolute value of the full data is used as the largest trace deviation. - Otherwise, the largest between the absolute value of :attr:`global_min` - and :attr:`global_max` is used instead. + By default, :attr:`use_global_bounds` is set to False and + :attr:`global_min` and :attr:`global_max` to 0.0, which means that one + of these value has to be set to create a meaningful plot. - By default, :attr:`use_global_bounds` is set to False and - :attr:`global_min` and :attr:`global_max` to 0.0, which means that one - of these value has to be set to create a meaningful plot. - - :attr:`~chaco.multi_line_plot.MultiLinePlot.scale`, - :attr:`~chaco.multi_line_plot.MultiLinePlot.offset`, - :attr:`~chaco.multi_line_plot.MultiLinePlot.normalized_amplitude` - - In addition to the rescaling done using the global bounds (see above), - each line is individually scaled by :attr:`normalized_amplitude` - (by default this is -0.5, but is normally it should be something like 1.0). - Finally, all the lines are moved by :attr:`offset` and multiplied by - :attr:`scale` (default are 0.0 and 1.0, respectively). +:attr:`~chaco.multi_line_plot.MultiLinePlot.scale`, :attr:`~chaco.multi_line_plot.MultiLinePlot.offset`, :attr:`~chaco.multi_line_plot.MultiLinePlot.normalized_amplitude` + In addition to the rescaling done using the global bounds (see above), + each line is individually scaled by :attr:`normalized_amplitude` + (by default this is -0.5, but is normally it should be something like 1.0). + Finally, all the lines are moved by :attr:`offset` and multiplied by + :attr:`scale` (default are 0.0 and 1.0, respectively). :class:`~chaco.multi_line_plot.MultiLinePlot` also defines the following parameters: - :attr:`~chaco.multi_line_plot.MultiLinePlot.line_width`, - :attr:`~chaco.multi_line_plot.MultiLinePlot.line_style` - - Control the thickness and style of the lines, as for - :ref:`line plots `. - - :attr:`~chaco.multi_line_plot.MultiLinePlot.color`, - :attr:`~chaco.multi_line_plot.MultiLinePlot.color_func` - - If :attr:`color_func` is None, all lines have the color defined - in :attr:`color`. Otherwise, :attr:`color_func` is a function - (or, more in general, a callable) that accept a single argument corresponding - to the index of the line and returns a RGBA 4-tuple. +:attr:`~chaco.multi_line_plot.MultiLinePlot.line_width`, :attr:`~chaco.multi_line_plot.MultiLinePlot.line_style` + Control the thickness and style of the lines, as for + :ref:`line plots `. - :attr:`~chaco.multi_line_plot.MultiLinePlot.fast_clip` +:attr:`~chaco.multi_line_plot.MultiLinePlot.color`, :attr:`~chaco.multi_line_plot.MultiLinePlot.color_func` + If :attr:`color_func` is None, all lines have the color defined + in :attr:`color`. Otherwise, :attr:`color_func` is a function + (or, more in general, a callable) that accept a single argument corresponding + to the index of the line and returns a RGBA 4-tuple. - If True, traces whose *base* y-coordinate is outside the value axis range - are not plotted, even if some of the data in the curve extends into the plot - region. (Default is False) +:attr:`~chaco.multi_line_plot.MultiLinePlot.fast_clip` + If True, traces whose *base* y-coordinate is outside the value axis range + are not plotted, even if some of the data in the curve extends into the plot + region. (Default is False) .. image:: images/user_guide/multiline_plot.png :width: 500px @@ -474,29 +461,29 @@ in Chaco are derived from the base class :class:`~chaco.base_countour_plot.BaseContourPlot`, which defines these common attributes: - :attr:`~chaco.base_countour_plot.BaseContourPlot.levels` - :attr:`levels` is used to define the values for which to draw a contour. - It can be either a list of values (floating point numbers); - a positive integer, in which - case the range of the value is divided in the given number of equally - spaced levels; or "auto" (default), which divides the total range in - 10 equally spaced levels +:attr:`~chaco.base_countour_plot.BaseContourPlot.levels` + :attr:`levels` is used to define the values for which to draw a contour. + It can be either a list of values (floating point numbers); + a positive integer, in which + case the range of the value is divided in the given number of equally + spaced levels; or "auto" (default), which divides the total range in + 10 equally spaced levels - :attr:`~chaco.base_countour_plot.BaseContourPlot.colors` - This attribute is used to define the color of the contours. :attr:`colors` - can be given as a color name, in which case all contours have the same - color, as a list of colors, or as a colormap. If the list of colors is - shorter than the number of levels, the values are repeated from the beginning - of the list. - If left unspecified, the contours are plot in black. - Colors are associated with levels of increasing value. +:attr:`~chaco.base_countour_plot.BaseContourPlot.colors` + This attribute is used to define the color of the contours. :attr:`colors` + can be given as a color name, in which case all contours have the same + color, as a list of colors, or as a colormap. If the list of colors is + shorter than the number of levels, the values are repeated from the beginning + of the list. + If left unspecified, the contours are plot in black. + Colors are associated with levels of increasing value. - :attr:`~chaco.base_countour_plot.BaseContourPlot.color_mapper` - If present, the color mapper for the colorbar. - TODO: not sure how it works +:attr:`~chaco.base_countour_plot.BaseContourPlot.color_mapper` + If present, the color mapper for the colorbar. + TODO: not sure how it works - :attr:`~chaco.base_countour_plot.BaseContourPlot.alpha` - Global alpha level for all contours. +:attr:`~chaco.base_countour_plot.BaseContourPlot.alpha` + Global alpha level for all contours. Contour Line Plot @@ -507,26 +494,26 @@ in :class:`~chaco.base_countour_plot.BaseContourPlot`, :class:`~chaco.base_countour_plot.ContourLinePlot` defines the following parameters: - :attr:`~chaco.base_countour_plot.ContourLinePlot.widths` - The thickness of the contour lines. - It can be either a scalar value, valid for all contour lines, or a list - of widths. If the list is too short with respect to the number of - contour lines, the values are repeated from the beginning of the list. - Widths are associated with levels of increasing value. - - :attr:`~chaco.base_countour_plot.ContourLinePlot.styles` - The style of the lines. It can either be a string that specifies the - style for all lines (allowed styles are 'solid', 'dot dash', 'dash', 'dot', - or 'long dash'), or a list of styles, one for each line. - If the list is too short with respect to the number of - contour lines, the values are repeated from the beginning of the list. - The default, 'signed', sets all lines corresponding to positive values to the - style given by the attribute - :attr:`~chaco.base_countour_plot.ContourLinePlot.positive_style` (default - is 'solid'), and all lines corresponding to negative values to - the style given by - :attr:`~chaco.base_countour_plot.ContourLinePlot.negative_style` - (default is 'dash'). +:attr:`~chaco.base_countour_plot.ContourLinePlot.widths` + The thickness of the contour lines. + It can be either a scalar value, valid for all contour lines, or a list + of widths. If the list is too short with respect to the number of + contour lines, the values are repeated from the beginning of the list. + Widths are associated with levels of increasing value. + +:attr:`~chaco.base_countour_plot.ContourLinePlot.styles` + The style of the lines. It can either be a string that specifies the + style for all lines (allowed styles are 'solid', 'dot dash', 'dash', 'dot', + or 'long dash'), or a list of styles, one for each line. + If the list is too short with respect to the number of + contour lines, the values are repeated from the beginning of the list. + The default, 'signed', sets all lines corresponding to positive values to the + style given by the attribute + :attr:`~chaco.base_countour_plot.ContourLinePlot.positive_style` (default + is 'solid'), and all lines corresponding to negative values to + the style given by + :attr:`~chaco.base_countour_plot.ContourLinePlot.negative_style` + (default is 'dash'). .. image:: images/user_guide/contour_line_plot.png :width: 500px @@ -555,18 +542,18 @@ are mapped to screen coordinates by :attr:`index_mapper` and In addition, the class :class:`~chaco.base_countour_plot.PolygonPlot` defines these parameters: - :attr:`~chaco.base_countour_plot.PolygonPlot.edge_color` - The color of the line on the edge of the polygon (default is black). +:attr:`~chaco.base_countour_plot.PolygonPlot.edge_color` + The color of the line on the edge of the polygon (default is black). - :attr:`~chaco.base_countour_plot.PolygonPlot.edge_width` - The thickness of the edge of the polygon (default is 1.0). +:attr:`~chaco.base_countour_plot.PolygonPlot.edge_width` + The thickness of the edge of the polygon (default is 1.0). - :attr:`~chaco.base_countour_plot.PolygonPlot.edge_style` - The line dash style for the edge of the polygon, one of 'solid' - (default), 'dot dash', 'dash', 'dot', or 'long dash'. +:attr:`~chaco.base_countour_plot.PolygonPlot.edge_style` + The line dash style for the edge of the polygon, one of 'solid' + (default), 'dot dash', 'dash', 'dot', or 'long dash'. - :attr:`~chaco.base_countour_plot.PolygonPlot.face_color` - The color of the face of the polygon (default is transparent). +:attr:`~chaco.base_countour_plot.PolygonPlot.face_color` + The color of the face of the polygon (default is transparent). .. image:: images/user_guide/polygon_plot.png :width: 500px @@ -588,22 +575,22 @@ Draws a set of rectangular bars, mostly used to plot histograms. The class :class:`~chaco.barplot.BarPlot` defines the attributes of regular X-Y plots, plus the following parameters: - :attr:`~chaco.barplot.BarPlot.starting_value` - While :attr:`~chaco.barplot.BarPlot.value` is a data source defining - the upper limit of the bars, :attr:`~chaco.barplot.BarPlot.starting_value` - can be used to define their bottom limit. Default is 0. - (Note: "upper" and "bottom" assume a horizontal layout for the plot.) +:attr:`~chaco.barplot.BarPlot.starting_value` + While :attr:`~chaco.barplot.BarPlot.value` is a data source defining + the upper limit of the bars, :attr:`~chaco.barplot.BarPlot.starting_value` + can be used to define their bottom limit. Default is 0. + (Note: "upper" and "bottom" assume a horizontal layout for the plot.) - :attr:`~chaco.barplot.BarPlot.bar_width_type` - Determines how to interpret the :attr:`bar_width` parameter. - If 'data' (default', the width is given in the units along the index - dimension of the data space. If 'screen', the width is given in pixels. +:attr:`~chaco.barplot.BarPlot.bar_width_type` + Determines how to interpret the :attr:`bar_width` parameter. + If 'data' (default', the width is given in the units along the index + dimension of the data space. If 'screen', the width is given in pixels. - :attr:`~chaco.barplot.BarPlot.bar_width` - The width of the bars (see :attr:`bar_width_type`). +:attr:`~chaco.barplot.BarPlot.bar_width` + The width of the bars (see :attr:`bar_width_type`). - :attr:`~chaco.barplot.BarPlot.fill_color` - The color of the bars. +:attr:`~chaco.barplot.BarPlot.fill_color` + The color of the bars. .. image:: images/user_guide/bar_plot.png :width: 500px @@ -624,14 +611,14 @@ Usually, :attr:`vectors` is an instance of :class:`~chaco.quiverplot.QuiverPlot` defines these parameters: - :attr:`~chaco.quiverplot.QuiverPlot.line_width` - Width of the lines that trace the arrows (default is 1.0). +:attr:`~chaco.quiverplot.QuiverPlot.line_width` + Width of the lines that trace the arrows (default is 1.0). - :attr:`~chaco.quiverplot.QuiverPlot.line_color` - The color of the arrows (default is black). +:attr:`~chaco.quiverplot.QuiverPlot.line_color` + The color of the arrows (default is black). - :attr:`~chaco.quiverplot.QuiverPlot.arrow_size` - The length of the arrowheads in pixels. +:attr:`~chaco.quiverplot.QuiverPlot.arrow_size` + The length of the arrowheads in pixels. .. image:: images/user_guide/quiver_plot.png @@ -656,28 +643,28 @@ coordinates, and adds circular polar coordinate axes. The aspect of the polar plot can be controlled with these parameters: - :attr:`~chaco.polar_line_renderer.PolarLineRenderer.line_width` - Width of the polar plot line (default is 1.0). +:attr:`~chaco.polar_line_renderer.PolarLineRenderer.line_width` + Width of the polar plot line (default is 1.0). - :attr:`~chaco.polar_line_renderer.PolarLineRenderer.line_style` - The style of the line, one of 'solid' (default), 'dot dash', 'dash', 'dot', - or 'long dash'. +:attr:`~chaco.polar_line_renderer.PolarLineRenderer.line_style` + The style of the line, one of 'solid' (default), 'dot dash', 'dash', 'dot', + or 'long dash'. - :attr:`~chaco.polar_line_renderer.PolarLineRenderer.color` - The color of the line. +:attr:`~chaco.polar_line_renderer.PolarLineRenderer.color` + The color of the line. - :attr:`~chaco.polar_line_renderer.PolarLineRenderer.grid_style` - The style of the lines composing the axis, one of 'solid','dot dash', - 'dash', 'dot' (default), or 'long dash'. +:attr:`~chaco.polar_line_renderer.PolarLineRenderer.grid_style` + The style of the lines composing the axis, one of 'solid','dot dash', + 'dash', 'dot' (default), or 'long dash'. - :attr:`~chaco.polar_line_renderer.PolarLineRenderer.grid_visible` - If True (default), the circular part of the axes is drawn. +:attr:`~chaco.polar_line_renderer.PolarLineRenderer.grid_visible` + If True (default), the circular part of the axes is drawn. - :attr:`~chaco.polar_line_renderer.PolarLineRenderer.origin_axis_visible` - If True (default), the radial part of the axes is drawn. +:attr:`~chaco.polar_line_renderer.PolarLineRenderer.origin_axis_visible` + If True (default), the radial part of the axes is drawn. - :attr:`~chaco.polar_line_renderer.PolarLineRenderer.origin_axis_width` - Width of the radial axis in pixels (default is 2.0). +:attr:`~chaco.polar_line_renderer.PolarLineRenderer.origin_axis_width` + Width of the radial axis in pixels (default is 2.0). .. image:: images/user_guide/polar_plot.png :width: 350px @@ -689,37 +676,36 @@ Jitter Plot A plot showing 1D data by adding a random jitter around the main axis. It can be useful for visualizing dense collections of points. -This plot has got a single mapper, -called :class:`~chaco.jitterplot.JitterPlot.mapper`. +This plot has got a single mapper, called :attr:`~chaco.jitterplot.JitterPlot.mapper`. Useful parameters are: - :attr:`~chaco.jitterplot.JitterPlot.jitter_width` - The size, in pixels, of the random jitter around the axis. +:attr:`~chaco.jitterplot.JitterPlot.jitter_width` + The size, in pixels, of the random jitter around the axis. - :attr:`~chaco.jitterplot.JitterPlot.marker` - The marker type, one of 'square'(default), 'circle', 'triangle', - 'inverted_triangle', 'plus', 'cross', 'diamond', 'dot', or 'pixel'. - One can also define a new marker shape by setting this parameter to 'custom', - and set the :attr:`~chaco.scatterplot.custom_symbol` parameter to - a :class:`CompiledPath` instance (see the file - ``demo/basic/scatter_custom_marker.py`` in the Chaco examples directory). +:attr:`~chaco.jitterplot.JitterPlot.marker` + The marker type, one of 'square'(default), 'circle', 'triangle', + 'inverted_triangle', 'plus', 'cross', 'diamond', 'dot', or 'pixel'. + One can also define a new marker shape by setting this parameter to 'custom', + and set the :attr:`~chaco.scatterplot.custom_symbol` parameter to + a :class:`CompiledPath` instance (see the file + ``demo/basic/scatter_custom_marker.py`` in the Chaco examples directory). - :attr:`~chaco.jitterplot.JitterPlot.marker_size` - Size of the marker in pixels, not including the outline (default is 4.0). +:attr:`~chaco.jitterplot.JitterPlot.marker_size` + Size of the marker in pixels, not including the outline (default is 4.0). - :attr:`~chaco.jitterplot.JitterPlot.line_width` - Width of the outline around the markers (default is 1.0). If this is 0.0, - no outline is drawn. +:attr:`~chaco.jitterplot.JitterPlot.line_width` + Width of the outline around the markers (default is 1.0). If this is 0.0, + no outline is drawn. - :attr:`~chaco.jitterplot.JitterPlot.color` - The fill color of the marker (default is black). +:attr:`~chaco.jitterplot.JitterPlot.color` + The fill color of the marker (default is black). - :attr:`~chaco.jitterplot.JitterPlot.outline_color` - The color of the outline to draw around the marker (default is black). +:attr:`~chaco.jitterplot.JitterPlot.outline_color` + The color of the outline to draw around the marker (default is black). .. image:: images/user_guide/jitter_plot.png :width: 500px -TODO: add description of color bar class +.. TODO: add description of color bar class diff --git a/docs/source/user_manual/plots.rst b/docs/source/user_manual/plots.rst new file mode 100644 index 000000000..06e50a3c4 --- /dev/null +++ b/docs/source/user_manual/plots.rst @@ -0,0 +1,252 @@ +.. _plots: + +=================== +Plots and Plot Data +=================== + +The primary interface that Chaco presents is the :py:class:`~chaco.plot.Plot` +class. Informally you can think of this as a single set of shared axes that +contain a collection of renderers within that view. It comes pre-configured +with most of the decorations that you might want, such as grids, titles and +legends, and those can easily be modified if desired. + +Plots Are Components +==================== + +The :py:class:`~chaco.plot.Plot` class is a subclass of the +:py:class:`~enable.component.Component` class, and so you can display a plot +in a TraitsUI using a :py:class:`~enable.component_editor.ComponentEditor` +as you would any other Enable :py:class:`~enable.component.Component`. +Usually this looks something like: + +.. literalinclude:: /../../examples/user_guide/power_function_example.py + :language: python + :lines: 12-20, 76-86 + +Because plots tend to consume a large amount of vertical space you typically +want to avoid displaying it in a group which shows labels on the left-hand +side, as this creates a lot of empty space. By grouping in a way like what +is shown above, you get the following, more pleasing layout: + +.. image:: images/power_function_example.png + :scale: 50% + +Since :py:class:`~chaco.plot.Plot` subclasses +:py:class:`~enable.component.Component`, you have the basic styling options +that :py:class:`~enable.component.Component` gives you, such as background +color, padding, borders, etc. However :py:class:`~chaco.plot.Plot` assumes +that you have substantial padding around it as the plot titles, axis ticks +and axis labels are rendered in the padding around the plot by default; but +you can frequently get more compact layout by reducing the padding on the +sides which do not have labels. + +Similarly, this means that you can use a plot in the same way that you would +any other Enable component, and it will work with Enable tools. So you could +have multiple :py:class:`~chaco.plot.Plot`s inside an enable +:py:class:`~enable.container.Container` or :py:class:`~chaco.canvas.Canvas` +and attach :py:class:`~enable.tools.move_tool.MoveTool` and +:py:class:`~enable.tools.resize_tool.ResizeTool` to them to allow the user +complete control over the location and size of the plots. + +Plot Data +========= + +The data for a :py:class:`~chaco.plot.Plot` is stored in an instance of an +:py:class:`~chaco.abstract_plot_data.AbstractPlotData` (and almost always +:py:class:`~chaco.array_plot_data.ArrayPlotData`). The plot data classes +provide a namespace that maps names to data so that the +:py:class:`~chaco.plot.Plot` can refer to the data by name when constructing +and modifying plot renderers. + +Usually the raw data is added to the plot data during initialization, and +the assigned names used as the data parameters for the plot factories: + +.. literalinclude:: /../../examples/user_guide/power_function_example.py + :language: python + :lines: 12-35, 53 + +After raw data has been added to the plot, it can be updated via the +:py:meth:`~chaco.array_plot_data.ArrayPlotData.set_data` method: + +.. literalinclude:: /../../examples/user_guide/power_function_example.py + :language: python + :lines: 60-63 + +Sometimes it is convenient to update multiple data values at the same +time, and in this case there is the +:py:meth:`~chaco.array_plot_data.ArrayPlotData.update_data` method: + +.. literalinclude:: /../../examples/user_guide/power_function_example.py + :language: python + :lines: 65-68 + +Peforming an update rather than multiple individual data setting +operations is preferable, where possible, since it triggers a single +combined update on any plots that are listening for changes to the +data rather than many smaller updates. + +Plot Factory Methods +==================== + +The :py:class:`~chaco.plot.Plot` class allws you to add multiple plots +of different types to the visualization your are constructing. It does +this via a family of factory methods, the most commonly used of which is +the :py:meth:`~chaco.plot.Plot.plot` method, but which include methods +for image plots, contour plots, candle plots and so on. + +All of these methods share that they expect parameters for: + +data + Either a name or a tuple of data names from the plot data that + should be used in the plot. The exact interpretation and number + of data values expected varies from method to method. + +name + A name to be given to the renderer or renderers created by the + method. The renderer can be retrieved from the + :py:class:`~chaco.plot.Plot` using its name. If a name is not + given, one is auto-generated. + +origin + An indication of the orientation of the plot. This is the + corner of the plot where the origin is located when looking + at data in the first quadrant (positive x and y). + +\*\*styles + Keyword arguments that are passed directly through to the + plot renderer, most commonly used to set things like colors, + line styles, marker types, and so on. + +Other common arguments that some, but not all, factory methods take +include whether to use linear or logarithmic axes, the bounds of +image or contour data in data space, and colormap information. + +The plot factory methods all return a list of plot renderers, all +of which are associated with the given name. + +The plot factory methods are: + +:py:meth:`~chaco.plot.Plot.plot` + The method for creating different types of XY plot subclasses. + In adddition to the parameters listed above, this takes a + ``type`` argument, which is a string naming the type of plot + renderer to create, such as ``line`` (the default), ``scatter``, + ``bar``, and so on. When called with many parameters, this + method may create multiple plot renderers of the same type. + +:py:meth:`~chaco.plot.Plot.img_plot` + The method for creating image plots. If the data has a shape + of (N, M, 3) or (N, M, 4) then it is treated as RGB or RGBA + data, otherwise for (N, M) shaped data a colormap will be + applied. This method can be given information about the + extent of the data in the index data space. This can come from + a named data source, from a hard-coded array of values, or from + a (low, high) tuple. If nothing is supplied then the bounds + for an image with N rows and M columns are (0, M) in the x + direction an (0, N) in the y direction. + +:py:meth:`~chaco.plot.Plot.contour_plot` + The method for creating contour plots. Like the + :py:meth:`~chaco.plot.Plot.plot` method this takes a `type` + argument to select between a ``"line"`` contour plot and a + filled ``"poly"`` polygon contour plot. This method can be + given information about the position of the data in the x and + y data spaces. This can come from a named data source, from a + hard-coded array of values, or from a (low, high) tuple. If + nothing is supplied then the locations of data points for an + image with N rows and M columns are (0, 1, ..., M-1) in the x + direction an (0, 1, ..., N-1) in the y direction. + +:py:meth:`~chaco.plot.Plot.candle_plot` + This method creates various styles of plots with error bars. + The type is inferred from the number of data values passed. + The first argument is always the index, but the remaining + arguments are variously interpreted as min and max values + for bar and whiskers, plus an optional central value. + It is up to the calling code to correctly derive the data + arrays: no aggregation is performed by the plot. + +:py:meth:`~chaco.plot.Plot.quiverplot` + The method creates a plot that places arrows at locations + determined by a list of x and y points. It expects three + data values: two arrays of length N for the points, and + a third (N, 2) array of direction vectors for the arrows. + +:py:meth:`~chaco.plot.Plot.plot_1d` + The method for creating different types of 1D plot subclasses. + In adddition to the parameters listed above, this takes a + ``type`` argument, which is a string naming the type of plot + renderer to create, such as ``scatter_1d`` (the default), + ``line_scatter_1d``, ``textplot_1d``, and so on. + + +The plot renderers for a :py:class:`~chaco.plot.Plot` instance are +available via the :py:attr:`~chaco.plot.Plot.plots` attribute, which +is a dictionary mapping plot names to a list of plots that match +that name. Once obtained, they can have styling attributes changed +or otherwise be manipulated. In particular, since the plot renderers +are alse :py:class:`enable.component.Component` subclasses, they can +have tools attached to them and otherwise be used as a component +might be. + +Plot renderers can be removed by calling the +:py:meth:`~chaco.plot.Plot.delplot` method with arguments of the +names of the plots to be removed. All plot renderers with +matching names will be deleted. + +Plot renderers can also be shown and hidden as groups by name using +the :py:meth:`~chaco.plot.Plot.hideplot` and +:py:meth:`~chaco.plot.Plot.showplot` methods. + +Plot Configuration +================== + +Since :py:class:`~chaco.plot.Plot` is a subclass of +:py:class:`~enable.component.Component` the options for changing background +and border properties that :py:class:`~enable.component.Component` +provides are available. + +The :py:class:`~chaco.plot.Plot` class comes pre-configured to display +basic plots in a reasonably clean way: plots are provided with axes and +grids by default, but not with any other sort of decoration. However +it is straightforward to remove these, or to add other basic decoration +such as titles and legends if they are desired. + +Title characteristics can be set directly via attributes such as +:py:attr:`~chaco.plot.Plot.title_text`, +:py:attr:`~chaco.plot.Plot.title_font`, +:py:attr:`~chaco.plot.Plot.title_color`, +:py:attr:`~chaco.plot.Plot.title_angle`, and +:py:attr:`~chaco.plot.Plot.title_position`. The title text can also be set +via the convenience property :py:attr:`~chaco.plot.Plot.title`, which has the +added side-effect of hiding the title if the text is the empty string. + +.. literalinclude:: /../../examples/user_guide/power_function_example.py + :language: python + :lines: 26-36, 42-44 + +Title text and other attributes can be updated dynamically and the plot will +update correctly to display the modified label. + +.. literalinclude:: /../../examples/user_guide/power_function_example.py + :language: python + :lines: 70-72 + +The plot class also provides a :py:class:`~chaco.legend.Legend` instance +that is hidden by default. It can be shown by toggling the visibility +of the legend. The positioning of the legend relative to the plot can be +set via the :py:attr:`~chaco.plot.Plot.legend_alignment` trait. Additional +configuration can be performed via the :py:class:`~chaco.legend.Legend` class +up to and including replacing it with a custom :py:class:`~chaco.legend.Legend` +subclass. + +.. literalinclude:: /../../examples/user_guide/power_function_example.py + :language: python + :lines: 26-36, 45-48 + +Axes and grids can be accessed either as "index" and "value" or "x" and "y" +depending on how the code is working with them. In general it is preferable +to use "index" and "value" as this takes into account the orientation of the +plot. Axes and grids can be removed by setting their visibility to False, +or setting the appropriate trait to None. Axes and grids have many +configuration options, detailed in their documentation. diff --git a/docs/source/user_manual/quickstart.rst b/docs/source/user_manual/quickstart.rst new file mode 100644 index 000000000..17ad2243f --- /dev/null +++ b/docs/source/user_manual/quickstart.rst @@ -0,0 +1,267 @@ +.. _quickstart: + + +########## +Quickstart +########## + ++----------------------------------------+--------------------------------------+ +|.. image:: images/simple_line.png |.. image:: images/scalar_function.png| +| :height: 300 px | :height: 300 px | +| :align: center | :align: center | ++----------------------------------------+--------------------------------------+ + +This section is meant to help users on well-supported platforms and common +Python environments get started using Chaco as quickly as possible. + + +Built-in Examples +================= + +Chaco ships with several examples for testing your installation and to show you +what Chaco can do. Almost all of the examples are stand-alone files that you +can run individually, from any location. Depending on how you installed Chaco, +you may or may not have the examples already. + +Location +-------- + +The examples are located in the :file:`examples/` subdirectory inside the root +of the Chaco source tree, next to :file:`docs/` and the :file:`chaco/` +directories. You can download the source code available on +`Github `_ or download a source +distribution from PyPi. If you don't want a local copy of the Chaco codebase, +you can browse the +`examples on GitHub `_. + +In the :file:`examples/demo/` directory, examples are classified by themes and +located in separate directories. Almost all of the Chaco examples are +standalone files that can be run individually. We will first show how to +execute them from the command line, and then we will show how to run Chaco in +an interactive way from IPython. This "shell" mode will be more familiar to +Matplotlib or MATLAB users. + +.. note:: + Some of these examples can be visualized in our + :ref:`annotated examples `. + + +First plots from the command line +--------------------------------- + +From the :file:`examples/demo` directory, run the ``simple_line`` example:: + + python simple_line.py + +This opens a plot of several Bessel functions with a legend. + +.. image:: images/simple_line.png + +You can interact with the plot in several ways: + +.. Ctrl-Left and Ctrl-Right don't work in OS X? + +* To pan the plot, hold down the left mouse button inside the plot area (but + not on the legend) and drag the mouse. + +* To zoom the plot: + + * Mouse wheel: scroll up to zoom in, and scroll down to zoom out (or the + reverse you're on a version of OS X with 'natural scrolling'). + + * Zoom box: Press :kbd:`z`, and then draw a box region to zoom in on. + (There is no box-based zoom out.) Press :kbd:`Ctrl-Left` and + :kbd:`Ctrl-Right` to go back and forward in your zoom box history. + + * Drag: hold down the right mouse button and drag the mouse up or down. Up + zooms in, and down zooms out. + + * For any of the above, press :kbd:`Escape` to reset the zoom to the + original view. + +* To move the legend, hold down the right mouse button inside the legend and + drag it around. Note that you can move the legend outside of the plot area. + +* To exit the plot, click the "close window" button on the window frame or (on + Mac) choose the Quit option on the Python menu. Alternatively, can you press + :kbd:`Ctrl-C` in the terminal. + +You can run most of the examples in the the :file:`examples/demo/basic/` +directory and the :file:`examples/demo/shell/` directory. The +:file:`examples/demo/advanced/` directory has some examples that require +additional data or packages. In particular, + +* :file:`spectrum.py` requires that you have PyAudio installed and a working + microphone. + +* :file:`data_cube.py` needs to download about 7.3mb of data from the Internet + the first time it is executed, so you must have a working Internet + connection. Once the data is downloaded, you can save it so you can run the + example offline in the future. + +For detailed information about each built-in example, see the :ref:`examples` +section. + + +First plots from IPython +------------------------ + +While all of the Chaco examples can be launched from the command line using the +standard Python interpreter, if you have IPython installed, you can poke around +them in a more interactive fashion. + +Chaco provides a subpackage, currently named the "Chaco Shell", for doing +command-line plotting like Matlab or Matplotlib. The examples in the +:file:`examples/demo/shell/` directory use this subpackage, and they are +particularly amenable to exploration with IPython. + +The first example we'll look at is the :file:`lines.py` example. First, we'll +run it using the standard Python interpreter:: + + python lines.py + +This shows two overlapping line plots. + +.. image:: images/lines.png + +You can interact with this plot just as in the previous section. + +Now close the plot, and start IPython with the ``--gui=qt`` [#guiqt]_ or +``--gui=wx`` option:: + + ipython --gui=qt + +This tells IPython to start a Qt or Wx mainloop in a background thread. Now +run the previous example again:: + + In [1]: run lines.py + +This displays the plot window, but gives you another IPython prompt. You can +now use various commands from the :mod:`chaco.shell` package to interact with +the plot. + +Import the shell commands:: + + In [2]: from chaco.shell import * + +Set the X-axis title:: + + In [3]: xtitle("X data") + +Toggle the legend:: + + In [4]: legend() + +After running these commands, your plot looks like this: + +.. image:: images/lines_final.png + +The :func:`chaco_commands` function display a list of commands with brief +descriptions. + +You can explore the Chaco object hierarchy, as well. The :mod:`chaco.shell` +commands are just convenience functions that wrap a rich object hierarchy that +comprise the actual plot. See the :ref:`tutorial_ipython` section for +information on all you can do with Chaco from within IPython. + + +Chaco plot embedded in a Traits application +=========================================== + +The previous section showed how Chaco can be used interactively similarly to +`Matlab` or Matplotlib's `pyplot` package. + +Now, let's create, from scratch, the simplest possible Chaco plot which is +embedded inside a `Traits `_ application. +This will require more work but will represent the basis for a potential +large-scale, custom and powerful rich client application. this is really what +Chaco has been written for. + +First, some imports to bring in necessary components:: + + from chaco.api import ArrayPlotData, Plot + from enable.component_editor import ComponentEditor + + from traits.api import HasTraits, Instance + from traitsui.api import View, Item + +The imports from :mod:`chaco` and :mod:`enable` support the creation of the +plot. The imports from :mod:`traits` bring in components to embed the plot +inside a Traits application. (Refer to the +`Traits documentation `_ for more details +about building an interactive application using Traits.) Now let's create a +Traits class with a view that contains only one element: a Chaco plot inside a +slightly customized window:: + + class MyPlot(HasTraits): + plot = Instance(Plot) + traits_view = View( + Item( + 'plot', + editor=ComponentEditor(), + show_label=False + ), + width=500, + height=500, + resizable=True, + title="My line plot" + ) + +A few options have been set to control the window containing the plot. Now, +when the plot is created, we would like to pass in our data. Let's assume the +data is a set of points with coordinates contained in two NumPy arrays ``x`` +and ``y``. So, adding an ``__init__`` method to create the Plot object looks as +follows:: + + class MyPlot(HasTraits): + plot = Instance(Plot) + traits_view = View( + Item( + 'plot', + editor=ComponentEditor(), + show_label=False + ), + width=500, + height=500, + resizable=True, + title="My line plot" + ) + + def __init__(self, x, y, *args, **kw): + super(MyPlot, self).__init__(*args, **kw) + plotdata = ArrayPlotData(x=x,y=y) + plot = Plot(plotdata) + plot.plot(("x","y"), type = "line", color = "blue") + plot.title = "sin(x)*x**3" + self.plot = plot + +Since it inherits from HasTraits, the new class can use all the power of +Traits, and the call to super() in its ``__init__`` method makes sure this +object possesses the attributes and methods of its parent class. Now let's use +our Traits object. Below, we generate some data, pass it to an instance of +MyPlot and call configure_traits to create the UI:: + + import numpy as np + x = np.linspace(-14,14,100) + y = np.sin(x)*x**3 + lineplot = MyPlot(x,y) + lineplot.configure_traits() + +The result should look like + +.. image:: images/mylineplot.png + +This might look like a lot of code to visualize a function, but this is a +relatively simple basis on top of which we can build full-featured applications +with custom UIs and custom tools. For example, the Traits object allows you to +create controls for your plot at a very high level, add these controls to the +UI with very little work, and add listeners to update the plot when the data +changes. Chaco also allows you to create custom tools to interact with the +plot and overlays that make these tools intuitive and visually appealing. + +.. rubric:: Footnotes + +.. [#guiqt] Starting from IPython 0.12, it is possible to use the Qt backend + with ``--gui=qt``. Make sure that the environment variable ``QT_API`` + is set correctly, as described `here + `_ diff --git a/docs/source/user_manual/resources.rst b/docs/source/user_manual/resources.rst deleted file mode 100644 index d2d3fbafa..000000000 --- a/docs/source/user_manual/resources.rst +++ /dev/null @@ -1,100 +0,0 @@ -.. _resources: - -===================== -Other Chaco resources -===================== - - -Chaco Gallery -============= -Examples of what can be done with Chaco is available in -the `Chaco gallery `_. - -.. _going_further: - -Further Reading and resources -============================= - -You can also learn more about Chaco by: - -* running :ref:`the tutorials ` included with the Chaco package, - -* following :ref:`demos of Chaco ` given during webinars Enthought to EPD subscribers, - -* reading :ref:`seminar slides ` posted on conference websites, - -* reading about :ref:`the API ` from the developer guide. - -* following the Enthought Tool Suite mailing list: enthought-dev@enthought.com - -.. _built_in_tutorials: - -Built-in tutorials ------------------- - -For more details on how to use Chaco to embed powerful plotting -functionality inside applications, refer to the :ref:`tutorials` page. -In particular, some tutorial examples were added into the -:file:`examples/tutorials/scipy2008/` directory. These examples are -numbered and introduce -concepts one at a time, going from a simple line plot to building a -custom overlay with its own trait editor and reusing an existing tool -from the built-in set of tools. You can browse them on the GitHub repository -at: -https://github.com/enthought/chaco/tree/master/examples/tutorials . -Finally, it is recommended to explore the examples -(:ref:`examples` section) as they are regularly updated to reflect the most recent -changes and recommended ways to use Chaco. - - -.. _chaco_webinars: - -Enthought webinars ------------------- -The video webinars given in as part of the Enthought webinar -series cover building interactive plotting using Chaco. If you are an -EPD user, you can find the video, the slides, and the demo code for -each webinar covering Chaco. - -* The first one (April 2010) demoes how to use Chaco as your plotting - tool (https://www.enthought.com/repo/epd/webinars/2010-04InteractiveChaco/ ). - -* The seconds (October 2010) illustrates how to building interactive 2D visualization (see - https://www.enthought.com/repo/epd/webinars/2010-10Building2DInteractiveVisualizations/ ). - - -.. _chaco_presentations: - - -Presentations -------------- - -There have been several presentations on Chaco at previous PyCon and -SciPy conferences: - -* Video recording of the latest Chaco presentation at SciPy 2011 at - http://conference.scipy.org/scipy2011/tutorials.php#corran - -* Follow the tutorial from the Scipy 2006 conference at - http://code.enthought.com/projects/files/chaco_scipy06/chaco_talk.html , - -* Follow the presentation of Chaco at the PyCon 2007 at - http://code.enthought.com/projects/files/chaco_pycon07/ . - -* `SciPy 2008 Tutorial slides (pdf) `_ - -.. _api_docs: - -Developers references and API Docs ------------------------------------ - -For developers and architects, - -* more details about the **current architecture and API** can be found in - the :ref:`programmers_reference`, - -* the API for Chaco 3.0 (in ETS 3.0) can be found at - http://code.enthought.com/projects/files/ETS3_API/enthought.chaco.html , - -* the API for Chaco2 (in ETS 2.7.1) can be found at - http://code.enthought.com/projects/files/ets_api/enthought.chaco2.html . diff --git a/docs/source/user_manual/tutorials_and_examples.rst b/docs/source/user_manual/tutorials_and_examples.rst deleted file mode 100644 index ace2ea303..000000000 --- a/docs/source/user_manual/tutorials_and_examples.rst +++ /dev/null @@ -1,45 +0,0 @@ - -.. _tutorials: - -Tutorials and examples -======================= - -Tutorials ---------- - -* :ref:`Tutorial: Interactive plotting with Chaco ` - - This is - the main Chaco tutorial and introduces the basic concepts of - how to use Chaco and Traits UI to do basic plots, customize - layout, and add interactivity. - -* :ref:`Tutorial: Using Chaco from IPython ` - - This tutorial - explains how to use Chaco from IPython using the Chaco ``shell`` - command-line plotting interface to build plots, in - a Matlab or gnuplot-like style. - -.. the webinars section here has been removed as the hyperlinks - dont exist and/or are broken. it will be readded once we - figure out how and where to host the webinars. - - -.. tutorial_wx - -Examples --------- - -* The :ref:`annotated examples ` is a useful visual resource - presenting a set of Chaco plots together with their source code. - -* :ref:`Modeling Van del Waal's Equations ` - is a complete example of creating a data - model and then using Traits and Chaco to rapidly create interactive - plot GUIs. - -* :ref:`Creating an interactive Hyetograph ` - is an example of a hyetograph (a plot of rainfall intensity in relation - to time) application. This example introduces the ``on_trait_listener`` - decorator and uses Chaco, simple Traits views, and live GUI interaction. diff --git a/examples/user_guide/power_function_example.py b/examples/user_guide/power_function_example.py new file mode 100644 index 000000000..23b97ac9b --- /dev/null +++ b/examples/user_guide/power_function_example.py @@ -0,0 +1,91 @@ +# (C) Copyright 2010-2019 Enthought, Inc., Austin, TX +# All rights reserved. + +import numpy as np + +from chaco.api import ArrayPlotData, Plot +from enable.api import ComponentEditor +from traits.api import Array, HasStrictTraits, Instance, Range, on_trait_change +from traitsui.api import Item, VGroup, View + + +class PowerFunctionExample(HasStrictTraits): + """ Display a plot of a power function. """ + + #: The plot holding the visualization + plot = Instance(Plot) + + #: The power of the monomial to use. + power = Range(0, 5, value=2) + + #: The x-values to plot. + x = Array(shape=(None,), dtype='float') + + # Trait defaults -------------------------------------------------------- + + def _plot_default(self): + y = self.x**self.power + plot_data = ArrayPlotData(x=self.x, y=y) + plot = Plot(plot_data) + plot.plot( + ('x', 'y'), + 'line', + name="power function", + color='auto' + ) + + # configure the plot + plot.padding_top = 25 + plot.border_visible = False + plot.index_grid.visible = False + plot.value_grid.visible = False + plot.title = "Power Function n={}".format(self.power) + plot.title_position = 'right' + plot.title_angle = -90 + plot.legend_alignment = 'ul' + plot.legend.border_visible = False + plot.legend.bgcolor = (0.9, 0.9, 0.9, 0.5) + plot.legend.visible = True + + plot.index_axis.title = "y" + plot.value_axis.title = "x" + + return plot + + def _x_default(self): + return np.linspace(-2.0, 2.0, 101) + + # Trait change handlers ------------------------------------------------- + + @on_trait_change('power') + def _update_y(self): + y = self.x**self.power + self.plot.data.set_data('y', y) + + @on_trait_change('x') + def _update_data(self): + y = self.x**self.power + self.plot.data.update_data(x=self.x, y=y) + + @on_trait_change('power') + def _update_title(self): + self.plot.title = "Power Function n={}".format(self.power) + + # TraitsUI view --------------------------------------------------------- + + view = View( + VGroup( + Item('plot', editor=ComponentEditor()), + VGroup( + Item('power'), + ), + show_labels=False, + ), + resizable=True, + title="Power Function Example" + ) + + +if __name__ == '__main__': + view = PowerFunctionExample() + view.configure_traits()