- Load normalized data in multiple tables to create a multidimensional cube.
- Define aggregated measures to provide application-specific and high-level insights.
- Build no-code interactive charts and tables in JupyterLab.
- Create dashboards in the built-in web app.
Getting started
From CSV to Cube
In this part of the tutorial, you will create your first cube from a CSV file and learn multidimensional concepts such as cube, dimension, hierarchy, measure. Let’s begin by starting a new session:Multidimensional concepts
A cube is a multidimensional view of some data, making it easy to explore, aggregate, filter and compare. It’s called a cube because each attribute of the data can be represented as a dimension of the cube:- Dimensions
- Sales
- Date
- Date
- Product
- Product
- Sale ID
- Sale ID
- Shop
- Shop
- Date
- Sales
- Measures
- Quantity.MEAN
- formatter: DOUBLE[#,###.00]
- Quantity.SUM
- formatter: DOUBLE[#,###.00]
- Unit price.MEAN
- formatter: DOUBLE[#,###.00]
- Unit price.SUM
- formatter: DOUBLE[#,###.00]
- contributors.COUNT
- formatter: INT[#,###]
- Quantity.MEAN
Interactive widget
So far we have usedcube.query() which returns a pandas DataFrame but a better way to visualize multidimensional data is a pivot table.
With Atoti’s JupyterLab extension, you can create interactive widgets such as pivot tables and charts directly into your notebook.
This will create a widget and open the Atoti tab on the left with tools to manipulate the widget.
Let’s start by creating a pivot table:
- Run
session.widget. - In the left panel, click on a measure such as Quantity.SUM to add it.
- Click on a hierarchy such as Date to get the quantity per date.
- Drag and drop another hierarchy such as Product to the Columns section to get the quantity sold per day and per product.


Drilldown and filters
Multidimensional analysis is meant to be done from top to bottom: start by visualizing the indicators at the top level then drilldown to explain the top figures with more details. For instance, we can visualize some measures per date then drilldown on Shop for a specific date, then see the products sold by a specific shop on this date. Using the previous cube representation, this is like zooming more and more on a part of the cube.

Dashboarding app
Being able to quickly build widgets inside a notebook without coding is nice to rapidly explore the data, iterate on your model and share some results. However, to provide richer insights, dashboards are even better. That’s why Atoti comes with a web app that can be accessed outside of the notebook and where widgets can be laid out to form dashboards. The app can be accessed with this link:
Enriching the cube
In the previous section, you have learned how to create a basic cube and manipulate it. We will now enrich this cube with additional attributes and more interesting measures.Join
Currently, we have very limited information about our products: only the ID. We can load a CSV containing more details into a new table:join them.
products_table won’t be inlined into sales_table.
Instead, this just declares a reference between these two tables that the cube can use to provide more analytical axes.
You can visualize the structure of the session’s tables:
- Dimensions
- Products
- Brand
- Brand
- Category
- Category
- Color
- Color
- Size
- Size
- Sub category
- Sub category
- Brand
- Sales
- Date
- Date
- Product
- Product
- Sale ID
- Sale ID
- Shop
- Shop
- Date
- Products


New measures
So far we have only used the default measures which are basic aggregations of the numeric columns. We can add new custom measures to our cube.Max
We’ll start with an aggregation taking the maximum price of the sales table:Fact-level operations
To compute aggregates based of data which comes directly from the columns of a table, you can pass the calculation directly to the desired aggregation function. This is more efficient than first converting the columns to measures before the aggregation. Let’s use this to compute the total amount earned from the sale of the products, as well as the average.
Margin
Now that the price of each product is available from the products table, we can compute the margin. We use theOriginScope to perform the multiplication of the quantity sold by the purchase price for each Product and then do the sum.

Cumulative sum over time
A cumulative sum is the partial sum of the data up to the current value. For instance, a cumulative sum over time can be used to show how some measure changes over time.
Average per shop
Aggregations can also be combined. For instance, we can sum inside a Shop: then take the average of this to see how much a table sales on average:Multilevel hierarchies
So far, all our hierarchies only had one level but it’s best to regroup attributes with a parent-child relationship in the same hierarchy. For example, we can group the Category, SubCategory and Product ID levels into a Product hierarchy:- Dimensions
- Products
- Brand
- Brand
- Color
- Color
- Product
- Category
- Sub category
- Product
- Size
- Size
- Brand
- Sales
- Date
- Date
- Product
- Product
- Sale ID
- Sale ID
- Shop
- Shop
- Date
- Shops
- City
- City
- Country
- Country
- Shop size
- Shop size
- State or region
- State or region
- City
- Products
- Dimensions
- Location
- Geography
- Country
- State or region
- City
- Geography
- Products
- Brand
- Brand
- Color
- Color
- Product
- Category
- Sub category
- Product
- Size
- Size
- Brand
- Sales
- Date
- Date
- Product
- Product
- Sale ID
- Sale ID
- Shop
- Shop
- Date
- Shops
- Shop size
- Shop size
- Shop size
- Location

Polishing the cube
Deleting or hiding measures
Some measures have been automatically created from numeric columns but are not useful. For instance, Unit Price.SUM does not really make sense as we never want to sum the unit prices. We can delete it:Measure folders
Measures can be rearranged into folders.- Measures
- 📁 Amount
- Amount.MEAN
- formatter: DOUBLE[#,###.00]
- Amount.SUM
- formatter: DOUBLE[#,###.00]
- Average amount per shop
- formatter: DOUBLE[#,###.00]
- Cumulative amount
- formatter: DOUBLE[#,###.00]
- Percent of parent amount
- formatter: DOUBLE[#,###.00]
- Amount.MEAN
- Margin
- formatter: DOUBLE[#,###.00]
- Margin rate
- formatter: DOUBLE[#,###.00]
- Max price
- formatter: DOUBLE[#,###.00]
- Purchase price.VALUE
- formatter: DOUBLE[#,###.00]
- Quantity.MEAN
- formatter: DOUBLE[#,###.00]
- Quantity.SUM
- formatter: DOUBLE[#,###.00]
- Unit price.MEAN
- formatter: DOUBLE[#,###.00]
- contributors.COUNT
- formatter: INT[#,###]
- 📁 Amount
Measure formatters
Some measures can be formatted for a nicer display. Classic examples of this is changing the number of decimals or adding a percent or a currency symbol. Let’s do this for our percent of parent amount and margin rate:Before
After
Simulations
Simulations are a way to compare several scenarios and do what-if analysis. This helps understanding how changing the source data or a piece of the model impact the key indicators. In Atoti, the data model is made of measures chained together. A simulation can be seen as changing one part of the model, either its source data or one of its measure definitions, and then evaluating how it impacts the following measures.Source simulation
Let’s start by changing the source. With pandas or Spark, if you want to compare two results for a different versions of the entry dataset you have to reapply all the transformations to your dataset. With Atoti, you only have to provide the new data and all the measures will be automatically available for both versions of the data. We will create a new scenario using pandas to modify the original dataset.

Parameter simulations
The other simulation technique is to create a parameter measure whose value can be changed for some coordinates. When creating the simulation, you can choose at which granularity the modification applies. For instance we can create a parameter measure whose value will change depending on the country. Doing that, we can answer questions such as “What happens if there is a crisis in France and we sell 20% less?”1 everywhere, but using the country_simulation we can change that.
By adding values in the table you can change the value of the parameter measure depending on the levels used in the simulation and the scenario.


Going further
You’ve learned all the basics to build a project with Atoti, from the concept of multidimensional analysis to powerful simulations. We now encourage you to try the library with your own data. You can also start to learn more advanced features such asSessionConfig, endpoint(), and array.