data_table.py 4.44 KB
Newer Older
1
2
3
4
# -*- coding: utf-8 -*-
"""Data_table class which is the base for the other data types like data_line,
data_complex and data_IQ. The idea is adapted from holoviews (holoviews.org)
and builds on pandas as excellent data processing tool.
5
6
7

Author: Christian Schneider <c.schneider@uibk.ac.at>
Date: 16.03.2018
8
9
10
"""
from .base import data_module_base
import pandas as pd
11
12
13
14
15
import numpy as np
from .plot_style import color_scheme
import holoviews as hv
hv.extension('bokeh')
import holoviews.operation.datashader as hd
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


class data_table(data_module_base):
    """Class for table like data with one or more independent variables and
    one or more dependent variables

    Parameters
    -----------
    data_arrays : list, array, np.array
        Data to save. Format should be
        [array_x, array_y, array_z, ...]
    """

    def __init__(self, data_arrays, data_names=None):
        super().__init__()
31
32
33
34
35
36
        # Create default names
        df_names = ['x{}'.format(i) for i in range(len(data_arrays))]
        # Replace default names by the names given
        if data_names:
            for idx in range(len(data_names)):
                if data_names[idx]:
37
                    df_names[idx] = data_names[idx]
38
        # Create dictionary for pandas dataframe
39
40
        tmp_dict = {}
        for idx, d in enumerate(data_arrays):
41
42
            tmp_dict[data_names[idx]] = data_arrays[idx]
        # Create dataframe
43
44
        self.df = pd.DataFrame(data=tmp_dict)

45
    def import_data(self, data_arrays, data_names=None):
46
47
48
49
50
51
52
53
54
55
56
57
        """Import data from new arrays. Naming highly recommencd!
        Assumes first given array is the array of the independant variable.
        Parameters
        -----------
        data_arrays : list, array, np.array
            List of data arrays. Structure
            [[x, x, x, x, ....], [y, y, y,....], ... ]
        name_list : list, array, np.array, None
            List of names for arrays:
            ['x1', 'y', 'Resistances', ... ]
        """
        if data_names:
58
            order_names = data_names
59
        else:
60
            order_names = self.df.columns
61
62

        for d, idx in zip(data_arrays[0],
63
64
                          list(self.df[order_names[0]]
                                       .index.reindex(data_arrays[0])[1])):
65
            if idx != -1:
66
67
68
69
                for i in range(1, len(data_arrays)):
                    # Use mean
                    self.df[order_names[i]][idx] += data_arrays[i]
                    self.df[order_names[i]][idx] /= 2
70
            else:
71
72
                self.df = self.df.append({key: value[idx]} for key, value
                                         in zip(order_names, data_arrays))
73
74

    def plot_hv(self, x=None, y=None, height=400, width=800,
75
                title='', **kwargs):
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
        """Plot table with Holoviews

        Parameters
        -----------
        x : None, str, list
            Column name(s) used for x axis
        y : None, str, list
            Column name(s) used for y axis
        height : int
            Height of plot in pixels
        width : int
            Width of plot in pixels
        """
        if x is None:
            x_vals = [self.df.keys()[0]]
        elif isinstance(x, (list, np.array)):
            # len(y) == len(x)
            x_vals = []
            for x_i in x:
                x_vals.append(x_i)
        else:
            x_vals = [x]

        if y is None:
            y_vals = [self.df.keys()[1]]
        elif isinstance(x, (list, np.array)):
            # len(y) == len(x)
            y_vals = []
            for y_i in y:
                y_vals.append(y_i)
        else:
            y_vals = [y]

        if len(y_vals) != len(x_vals):
            for i in range(len(y_vals) - len(x_vals)):
                x_vals.append(self.df.keys()[0])

        # Plot FIRST element
114
115
        hv.opts({'Curve': {'style': kwargs}})
        s = hv.Scatter(self.df, x_vals[0], y_vals[0], label=title)
116
117
118
119
120
121
122
123
124
125
126
        scatter_plots = hd.dynspread(hd.datashade(hv.Curve(s),
                                                  cmap=[color_scheme[0]]))
        # Plot the other elements
        if len(x_vals) > 2:
            for x_i, y_i, c in zip(x_vals[1:], y_vals[1:], color_scheme[1:]):
                s = hv.Scatter(self.df, x_i, y_i, label=y_i)
                scatter_plots *= hd.dynspread(hd.datashade(hv.Curve(s),
                                                           cmap=[c]))

        return scatter_plots.opts(plot=dict(height=height, width=width,
                                            show_grid=True))