Help with matrix 3d xarray and ObjectProperty

34 views
Skip to first unread message

Walmir Paiva

unread,
Feb 23, 2019, 3:54:41 PM2/23/19
to Kivy users support

Hello,

I would like help for a problem I am facing.
I'm building an application that uses a matrix-based 3d xarray data model (http://xarray.pydata.org/en/stable/index.html).

I would like to preserve the data in an ObjectProperty, to get the bind functionality, but apparently this property is not working with this object type.


Example code:


# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import  ObjectProperty
from kivy.lang import Builder
from kivy.clock import mainthread

import pandas as pd
import numpy as np
import xarray as xr

Builder.load_string('''
<RootWidget>:
    Button:
        text: '
click to update/print current xarray dataset'
        on_press: root.change_data()
    Button:
        text: '
click to print objectproperty'
        on_press: root.print_object()

'''
)


class RootWidget(BoxLayout):
    xarray_obj
= ObjectProperty(allownone=True)
   
   
def __init__(self, **kwargs):
       
super(RootWidget, self).__init__(**kwargs)
       
       
self.create_dataset_base()
       
self.bind(xarray_obj=self.print_xarray_obj)
   
   
def create_dataset_base(self):
       
#creates a dataset like a 3d array (x: price column, y: products id, z: stores), with empty database
        store
= ['Walmart', 'Dia']
        list_id
= ['id_1', 'id_2', 'id_3', 'id_4' ]
        price
= ['unit_price']
        temp_3d_array
= np.empty((len(store), len(list_id), len(price)))
       
       
#object xarray
       
self.ds_base = xr.Dataset({'store_price':(['stores', 'ids',  'prices'], temp_3d_array)},
            coords
={'ids':list_id, 'stores': store, 'prices': price})
   
       
#fill dataset  
        df_Walmart_price
= pd.DataFrame({
           
'price':[10.0, 20.0, 30.0, 40.0]
           
}, index = ['id_1', 'id_2', 'id_3', 'id_4' ])
         
        df_Dia_price
= pd.DataFrame({
           
'price':[12.50, 18.75,  32.43, 37.0]
           
}, index = ['id_1', 'id_2', 'id_3', 'id_4' ])
       
       
self.ds_base['store_price'].loc[dict(stores= 'Walmart')] = df_Walmart_price
       
self.ds_base['store_price'].loc[dict(stores= 'Dia')] = df_Dia_price
       
       
#assigns dataset base to objectproperty
       
self.xarray_obj = self.ds_base
       
#self.xarray_obj = 'testestestestest'  # to test other object type - works correctly
       
       
print(self.ds_base.store_price)   #  to confirm dataset
       
       
print('type object xarray - ', type(self.ds_base))
       
print('id object xarray - ', id(self.ds_base))
       
       
print('type objectproperty - ', type(self.xarray_obj))
       
print('id objectproperty - ', id(self.xarray_obj))
       
print(self.xarray_obj)
   
   
def change_data(self):
       
#creates new dataset after manipulating data
        new_dataset
= self.ds_base.copy(deep=True)
       
       
#to transform into pandas dataframe for calculation
        df_temp
= self.ds_base['store_price'].loc[dict(stores= 'Walmart')].to_pandas()
        df_temp
['unit_price'] = df_temp['unit_price']*2 #doubling the value of the price column
       
       
#assigns dataframe to dataset
        new_dataset
['store_price'].loc[dict(stores= 'Walmart')] = df_temp
       
       
#assigns dataset base to objectproperty
       
self.xarray_obj = new_dataset
       
#self.xarray_obj = 'foofoofoofoofoo'  #to test other object type - works correctly
       
       
print(new_dataset.store_price) #to confirm calculation
       
       
print(type(new_dataset))
       
print(id(new_dataset))    
       
       
print(id(self.xarray_obj))
       
print(self.xarray_obj)

   
@mainthread
   
def print_xarray_obj(self, *args):
       
#bind test
       
print('ok - changed')
       
print(args)
   
   
def print_object(self):
       
print(self.xarray_obj)


class TestApp(App):
   
def build(self):
       
return RootWidget()


TestApp().run()

If you can show me what I'm doing wrong, I appreciate it.

Thanks

ZenCODE

unread,
Feb 24, 2019, 2:25:07 AM2/24/19
to Kivy users support
Try

    def on_xarray_obj(self, widget, value):
        print("This fires")


Walmir Paiva

unread,
Feb 25, 2019, 6:04:47 AM2/25/19
to kivy-...@googlegroups.com
Thanks for the reply ZenCode, but it did not work.It does not recognize the object change.
Walmir

--
You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/Y9xVvQ0rqBs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+...@googlegroups.com.
To post to this group, send email to kivy-...@googlegroups.com.
Visit this group at https://groups.google.com/group/kivy-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/c3a1587a-e16e-4e65-b443-52ac610435e5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ZenCODE

unread,
Feb 25, 2019, 3:51:14 PM2/25/19
to Kivy users support
Bizarre. It's not firing because xarray_obj stays None, even after you re-assign it with

    self.xarray_obj = self.ds_base

self.ds_base is a dataset, but for some very weird reason, the assignment does nothing! As you say in your code, assigning other objects works. There must be some black magic around xarray, or something in the kivy ObjectProperty that prevents assignment. I will try looking into that more closely...

Gabriel Pettier

unread,
Feb 25, 2019, 4:54:28 PM2/25/19
to kivy-...@googlegroups.com
You certainly want to look at how ListProperty works, and apply the same
kind of logic, that is, wrapping the object into another one (as
ObservableList is used by ListProperty), that overrides the basic
operation to dispatch changes.
>--
>You received this message because you are subscribed to the Google Groups "Kivy users support" group.
>To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
>To post to this group, send email to kivy-...@googlegroups.com.
>Visit this group at https://groups.google.com/group/kivy-users.
>To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/4e7d571d-f4b2-41bd-8e56-99a9949ac0e5%40googlegroups.com.

Walmir Paiva

unread,
Feb 26, 2019, 7:13:52 AM2/26/19
to Kivy users support
Tanks tshirtman for the sugestion, but Listproperty does something even more bizarre, just save the string with the name of the variable (dictionary key).

Black magic... :)

After a few attempts,using ObjectProperty, I got into that ugly hack that worked:

        temp_list = []
        temp_list
.append(new_dataset)
       
#assigns dataset to objectproperty
       
self.xarray_obj = None
       
self.xarray_obj = temp_list

Adds a bit of complexity ... but it's what we have for the moment.

Thanks
Walmir



Gabriel Pettier

unread,
Feb 26, 2019, 9:18:06 AM2/26/19
to kivy-...@googlegroups.com
yes, that's a hack ^^, if it works for you, good enough, but if you
wanted a transparent management on edit, you need to create a new
property type, using the same kind of logic as ListProperty and
ObservableList, not using them directly, just taking inspiration.
>--
>You received this message because you are subscribed to the Google Groups "Kivy users support" group.
>To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
>To post to this group, send email to kivy-...@googlegroups.com.
>Visit this group at https://groups.google.com/group/kivy-users.
>To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/86e81d82-3787-48a8-8f6c-0659452df0b1%40googlegroups.com.

Walmir Paiva

unread,
Feb 26, 2019, 12:09:02 PM2/26/19
to Kivy users support
In fact it is generating more complexity than I thought.
In the example worked, but in the real case it is not working properly.
I still can not understand it yet.
I would very much like to follow your suggestion and try to create a new property type, but I think maybe my knowledge of python and kivy is not enough.
If you can tell me where to find some example or guide me, I would greatly appreciate it.

Walmir Paiva

unread,
Feb 28, 2019, 12:36:48 PM2/28/19
to Kivy users support
Another hack that works in the real case:

        #assigns dataset to objectproperty
        temp_dict
= {}
        temp_dict
['ds'] =new_dataset
       
self.xarray_obj = temp_dict

Walmir

Reply all
Reply to author
Forward
0 new messages