def show_all(self, **kwargs): """ Writes self.objects dictionary as a JS script, i.e. all plots declared in all instances that inherit from class Graph. :return: """ plots = "[" # Setting raw data (lists) to variable names in JS. for variable, value in self.objects.items(): self.script[self.div_id] += "var {variable} = {value}; \n".format( variable=var(variable, True), value=value) self.script[self.div_id] += "\n" # Beautifying. for v_name, obj in self.objects.items( ): # Writing JS objects (that will be plotted) obj = var(obj, decode=True) # Escaping all references to variables self.script[self.div_id] += obj plots += v_name[1:-1] + ", " plots = plots[:-2] plots += "]" self.make_layout(**kwargs) self.script[self.div_id] += self.layout self.script[self.div_id] += "Plotly.newPlot({div_name}, {plots}, layout);"\ .format(div_name=escape(self.div_id), plots=plots) return self.script
def plot(self, x, y, mode="markers", **kwargs): """ :param x: List containing x-axis values :param y: List containing y-axis values :param mode: Show "markers", "markers+lines" or "lines". Default to "markers". :param kwargs: Attributes of the scatter plot. :return: """ # Sanity check - is data in correct format? if str(type(x)) != "<class 'list'>" or str(type(y)) != "<class 'list'>" \ or len(x) != len(y) or len(x) == 0 or len(y) == 0: raise TypeError( "Expected both x and y to be of type list of equal length > 0, not {type_x} and {type_y}" "of lengths {len_x} and {len_y}".format(type_x=str(type(x)), type_y=str(type(y)), len_x=str(len(x)), len_y=str(len(y)))) # Assigning names for JS variables when written to JS script. v_name_x = var("x" + str(len(self.instance_objects))) v_name_y = var("y" + str(len(self.instance_objects))) # Adding data to instance dictionary. self.data[v_name_x] = x self.data[v_name_y] = y self.finish_plot(x=v_name_x, y=v_name_y, mode=mode, **kwargs) return
def show(self, **kwargs): """ :param kwargs: Attributes of Plotly.animate function :return: """ self.attributes = Data(**kwargs).json anim_attr_js = jsify(self.attributes) self.script[self.div_id] += "\n\n" # Beautifying before writing animation code self.script[self.div_id] += "var is_paused = true;\n" # Boolean for play/pause implementation. variables_str = "" for plot in self.variables: variables_str += "{" for key, variable in plot.items(): variables_str += "{key}: {var}.slice(0, counter_{var}), ".format(key=key, var=var(variable, True)) # Making counter for every variable self.script[self.div_id] += "var counter_{var} = 0;\n".format(var=var(variable, True)) # Setting up maximum value for counter for each variable self.script[self.div_id] += "var counter_{var}_lim = {var}.length;\n".format( var=var(variable, True)) variables_str = variables_str[:-2] variables_str += "}, " # Making ready to write next object. variables_str = variables_str[:-2] traces = list(range(len(self.variables))) # Writing JS to create animation. anim_script = "function update() { \n\t if (!is_paused) {\n\t\t" # Function to show next frame for i in range(0, len(self.variables)): for key, variable in self.variables[i].items(): anim_script += "counter_{var}++; \n\t\t".format(var=var(variable, True)) # Increment counter. # If last index reached, reset index and hence loop animation. anim_script += "if (counter_{var} === counter_{var}_lim) {{\n\t\t\t" \ "counter_{var} = 0;\n\t\t}}\n\t\t".format(var=var(variable, True)) anim_script += "Plotly.animate({div_id}, {{data: [".format(div_id=self.div_id) anim_script += "{variables}], ".format(variables=variables_str) # Data to show in current frame. anim_script += "traces: {traces}}}, ".format(traces=traces) # Labeling traces. anim_script += "{anim_attr}".format(anim_attr=anim_attr_js) # Adding attributes. anim_script = anim_script[:-3] # Removing "};" in jsified attributes. anim_script += "}); \n\t\t" # End of Plotly.animate function. anim_script += "requestAnimationFrame(update); \n\t}\n}\n" # End of update function anim_script += "requestAnimationFrame(update); \n" # Calling animation function for first time. self.script[self.div_id] += anim_script self.graph.script[self.div_id] = self.script[self.div_id] # Updating graph script continuity_buttons = Button(self.graph, self.div_id[1:-1] + "_btn") # Passing graph script to button maker. self.script[self.div_id] = continuity_buttons.add_play_button() # Making play button. self.script[self.div_id] = continuity_buttons.add_reset_button(1) # Making reset button. self.graph.script[self.div_id] = self.script[self.div_id] # Updating graph script. return self.graph
def draw(self, **kwargs): """ :param kwargs: Names of variables that are to be animated. :return: """ # Modifying existing script to ensure the first frame is defined by data points in index 0 of data list. tmp = {} # Temporary dictionary. for key, variable in kwargs.items(): tmp[key] = var(variable) # Putting each variable in dictionary as a variable self.variables.append(tmp) return
def animate(self, **kwargs): """ :param kwargs: Names of variables that are to be animated. :return: """ # Modifying existing script to ensure the first frame is defined by data points in index 0 of data list. tmp = {} # Temporary dictionary for key, variable in kwargs.items(): tmp[key] = var(variable) # Putting each variable in dictionary as a variable self.script[self.div_id] = self.script[self.div_id]\ .replace(key + ": " + variable, key + ": " + variable + "[0]") self.variables.append(tmp) return
def show(self, **kwargs): """ Writes objects in self.data as a JS script, i.e. only the plots that exist in the declared instance. :param kwargs: Any attribute-value pair that needs to be written to the layout variable. :return: """ plots = "[" # Setting raw data (lists) to variable names in JS. for variable, value in self.data.items(): self.script[self.div_id] += "var {variable} = {value}; \n".format( variable=var(variable, True), value=value) traces = list(range(len(self.instance_objects.items()))) self.script[self.div_id] += "\n" # Beautifying. for v_name, obj in self.instance_objects.items( ): # Writing JS objects (that will be plotted) obj = var(obj, decode=True) # Escaping all references to variables self.script[self.div_id] += obj plots += v_name[1:-1] + ", " plots = plots[:-2] plots += "]" self.make_layout(**kwargs) self.script[self.div_id] += self.layout self.script[self.div_id] += "function plot() {{\n\t" \ "Plotly.newPlot({div_name}, {{data: {plots}, traces: {traces}, layout: layout}}); \n\t " \ "}} \n\n" \ "plot();"\ .format(div_name=escape(self.div_id), traces=traces, plots=plots) return self.script
def plot(self, z, **kwargs): """ :param z: List containing lines that make up the surface. :param kwargs: Attributes of the plot. :return: """ # Sanity check - is data in correct format? if str(type(z)) != "<class 'list'>" or len(z) == 0: raise TypeError( "Expected list of length >= 1, not {type} of length {length}". format(type=str(type(z)), length=len(z))) v_name_z = var("z" + str(len(self.instance_objects))) self.data[v_name_z] = z self.finish_plot(z=v_name_z, **kwargs) return