Datapane 0.9: Data stories

When we launched the Datapane framework in March, our focus was on being the simplest way to share results, such as interactive plots or a datasets, from Python.

As use of Datapane started to grow, we got to really dig into what people were trying to communicate with their Python analyses. More often than not, what they were trying to accomplish wasn't just sharing a dataset or a plot in isolation - they needed to add context around it to communicate effectively to their viewers. They were using data science to tell stories and share knowledge.

Inside of companies, we started to see a lot of people building richer reports than we originally imagined. On the public Datapane, many content writers accomplished this by embedding parts of their reports into Reddit and Medium, where they write richer text-heavy content.

One of the biggest bits of feedback from users was that they wanted a way to tell data stories which:

  1. Told a story by combining text with interactive plots, datasets, tables, and files
  2. Provided more interactive and customisable experiences for their viewers, instead of a sequential list of raw results

We've been working hard with these users to build features which make it really easy to tell beautiful data stories using Datapane's framework. Some features build on some of our existing features – such as Markdown – while some and completely new. We hope that these features will help data scientists build awesome, unique experiences for their consumers.

Text-centric reports

One of the things people struggled with when creating text-heavy reports on Datapane was having to write reports as lists of strings and plots. Interspersing Markdown and plots works well if you have a few headings, but it's hard when you are writing a text-rich report - such as a blogpost or article. To make this easier, our first idea was to build a web text-editor; but, from speaking to users, we learned that many of them were comfortable with Markdown and had a local editor already.

In response to this feedback, we've added a format option, which allows you to write a single block of Markdown (either in your report, or in a separate file), and template it with your other blocks.

import seaborn as sns
import altair as alt 
import datapane as dp

md = """

For example, if we want to visualize the number of people in each class within the interval we select a point chart between age and fare, we could do something like this.

{{plot}}

Altair allows you to create some extremely interactive plots which do on-the-fly calculations — without even requiring a running Python server!

"""

titanic = sns.load_dataset("titanic")

points = alt.Chart(titanic).mark_point().encode(
    x='age:Q',
    color='class:N',
    y='fare:Q',
).interactive().properties(width='container')

dp.Report(
  dp.Text(md).format(plot=points)
).publish(name='altair_example')

To do this, use double braces to specify where you want your other blocks to appear throughout your text. Alternatively, you can write your whole post in your favourite local Markdown editor, and import the file:

dp.Report(
  dp.Text(file='markdown.md').format(
    plot=plot, 
  )
).publish(name='altair_example')

We hope that this will made it easy for users to build text-rich whitepapers, articles, and blogposts using Markdown, Python, and Datapane.

Pages and Layouts

When we first released Datapane, it only supported a list of blocks and a single column – not a million miles off of a Jupyter Notebook. Many users needed a way to build more flexible grid components, and in October we released our layout features to allow the building of grid layouts.

We're pleased to announce we're adding a great new feature to this: Pages. Pages do what they say in the tin, and allow you to have multiple pages in your report which your users can navigate through tabs – without writing any HTML or CSS!

import seaborn as sns
import altair as alt 
import datapane as dp

titanic = sns.load_dataset("titanic")

points = alt.Chart(titanic).mark_point().encode(
    x='age:Q',
    color='class:N',
    y='fare:Q',
).interactive().properties(width='container')

dp.Report(
  dp.Page(
    label="Titanic Dataset",
    blocks=["### Dataset", titanic]
  ),
  dp.Page(
    label="Titanic Plot",
    blocks=["### Plot", points]
  )
).publish(name='altair_example_pages')

We've been using this internally to create multiple scenarios, add full source code to reports, and single reports which previously would have had to be multiple reports.

Dropdowns and Tabs

Pages work at the top-level of the report, and many users also wanted to have dynamic components inside of reports – such as tabs and drop-downs.

What if we want our titanic data above, but want to allow the user to choose whether they wanted to view the whole dataset, or a description of the dataset? Instead of making you include them both side by side, we've added dp.Select, which takes other blocks and turns them into tabs or drop downs.

This is also a great block for showing the source code behind a plot or dataset for documentation (which most of your viewers may not want to see). For instance, to see the source code of the Select component, click on the "Source code" tab.

Part of Datapane's mission is to be completely standalone, so none of these interactive elements require you to run or maintain a Python server – your report is pure HTML. You can publish them on datapane.com for free, embed them into your own site, or export them and host them on a static site such as GitHub pages.

Better Tables

Our primary Table component was built for large data with interactive filtering and sorting. We thought this was going to be the most common format, but learned that it isn't always the best option - many users wanted more styled display-focused tables, where they could show correlations, embed bar charts and histograms, and highlight anomalies, instead of a way to display millions of cells.

Many users were using our Markdown component to build a table, and we looked at building our own, before settling on supporting Pandas HTML tables. This allows us to support Pandas Styling and is a natural fit for our HTML reports, making it simple to build beautiful styled tables like this:

As part of this, we are making this the default Table component, and renaming our interactive component for larger datasets as DataTable.

HTML

Although users like being able to create reports without touching HTML, sometimes it's helpful to be able to pull in another UI library or custom component – for instance, maybe you want to include your company's logo or styling. To allow this for power users, we've added an HTML component which you can use anywhere in your Datapane report.

Big Number

Sometimes one statistic or KPI is the most important thing in your report - and we had a few users who were missing this from their BI tools. To save you the trouble of building one using HTML, we've included a BigNumber component for you (built with the amazing TailwindCSS library).

import datapane as dp

dp.Report(
   dp.Group(
      dp.BigNumber(
         heading="Number of percentage points", 
         value="84%",
         change="2%",
         is_upward_change=True
      ),
      dp.BigNumber(
         heading="Simple Statistic", 
         value=100
      ),
      columns=2
   )
)

Conclusion

This is the most excited we've been about a Datapane release, and we're really looking forward to seeing what the community builds using these new blocks. If you need a hand, or run into any bugs, please reach out on our GitHub. Want to chat or share something you're building? Join our new community on Slack.

Leo Anthias

Leo Anthias