materialsproject/MPContribs

Unclear instructions on how df labels work

Andrew-S-Rosen opened this issue · 2 comments

I'm a bit perplexed about how the dataframe labels are supposed to be set in the tables.

Here is what I have.

isotherm_df.attrs = {
    "name": "isotherm" + gas,
    "title": "Isotherm for " + gas,
    "labels": {
        "pressure": "Pressure (bar)", # I also tried "index"
        "loading_absolute_avg": "Absolute loading (avg)",
        "loading_absolute_dev": "Absolute loading (dev)",
        "enthalpy_of_adsorption_avg": "Enthalpy of adsorption (avg)",
        "enthalpy_of_adsorption_dev": "Enthalpy of adsorption (dev)",
    },
}

On submitting contributions, I get

Output exceeds the [size limit](command:workbench.action.openSettings?%5B%22notebook.output.textLineLimit%22%5D). Open the full output data[ in a text editor](command:workbench.action.openLargeOutput?ba9a3f54-15f4-44fb-b85e-9fab6bb48f5b)
Prepare: 100%|██████████| 1/1 [00:00<00:00, 50.00it/s]
Traceback (most recent call last):
  File "/root/.local/lib/python3.9/site-packages/flask_mongorest/views.py", line 191, in _dispatch_request
    return super(ResourceView, self).dispatch_request(*args, **kwargs)
  File "/root/.local/lib/python3.9/site-packages/flask/views.py", line 188, in dispatch_request
    return current_app.ensure_sync(meth)(**kwargs)
  File "/root/.local/lib/python3.9/site-packages/flask_mongorest/views.py", line 389, in post
    self.create_object(**kwargs)
  File "/root/.local/lib/python3.9/site-packages/flask_mongorest/views.py", line 408, in create_object
    self._resource.validate_request()
  File "/root/.local/lib/python3.9/site-packages/flask_mongorest/resources.py", line 708, in validate_request
    self.data = self.schema().load(self.data, partial=partial)
  File "/root/.local/lib/python3.9/site-packages/marshmallow/schema.py", line 722, in load
    return self._do_load(
  File "/root/.local/lib/python3.9/site-packages/marshmallow/schema.py", line 861, in _do_load
    result = self._deserialize(
  File "/root/.local/lib/python3.9/site-packages/marshmallow/schema.py", line 664, in _deserialize
    value = self._call_and_store(
  File "/root/.local/lib/python3.9/site-packages/marshmallow/schema.py", line 500, in _call_and_store
    value = getter_func(data)
  File "/root/.local/lib/python3.9/site-packages/marshmallow/schema.py", line 661, in <lambda>
    getter = lambda val: field_obj.deserialize(
  File "/root/.local/lib/python3.9/site-packages/marshmallow/fields.py", line 368, in deserialize
    output = self._deserialize(value, attr, data, **kwargs)
  File "/root/.local/lib/python3.9/site-packages/marshmallow/fields.py", line 784, in _deserialize
...
    raise FieldDoesNotExist(msg)
mongoengine.errors.FieldDoesNotExist: The fields "{'enthalpy_of_adsorption_dev', 'enthalpy_of_adsorption_avg', 'pressure', 'loading_absolute_dev', 'loading_absolute_avg'}" do not exist on the document "Labels"
...

Here is how my dataframe is structured:

image

labels only accepts the keys index (x-axis label), value (y-axis label), and variable (legend name/title) right now. The names for the traces as they appear in the legend are taken from the column names/headers as stored in the Dataframe. Technically, labels.index would not need to be set if you've used df.set_index() to set one of the columns as index or explicitly df.index.name (unless you want to display something different as x-axis label). We could consider to allow renaming column names / traces through df.attrs.labels as in plotly express but it's simpler and cleaner (from an API point of view) to keep column names and auto-generated graphs in sync IMO.

df.attrs = {
    "name": "my name for this df",
    "title": "title",
    "labels": {
          "index": "x axis label",
          "value": "y axis label",
          "variable": "legend name/title"
    }
}

If you're working in a notebook environment, you can preview what MPContribs would do with df.attrs by using the Table class provided by mpcontribs-client:

from mpcontribs.client import Table
table = Table(df)
table.display()

Ah, okay thanks!!