from kivycharts.graph import * from kivy.clock import Clock import numpy as np if __name__ == '__main__': import itertools from math import sin, cos, pi from random import randrange from kivy.utils import get_color_from_hex as rgb from kivy.uix.boxlayout import BoxLayout from kivy.app import App class TestApp(App): def build(self): b = BoxLayout(orientation='vertical') # example of a custom theme colors = itertools.cycle([ rgb('0000FF'), rgb('dc7062'), rgb('66a8d4'), rgb('e5b060')]) graph_theme = { 'label_options': { 'color': rgb('444444'), # color of tick labels and titles 'bold': True}, 'background_color': rgb('f8f8f2'), # canvas background color 'tick_color': rgb('808080'), # ticks and grid 'border_color': rgb('808080')} # border drawn around each graph graph = Graph( xlabel='Cheese', ylabel='Apples', # x_ticks_minor=5, # x_ticks_major=25, x_ticks_major=5, y_ticks_major=1, y_grid_label=True, x_grid_label=True, padding=5, xlog=False, ylog=False, x_grid=True, y_grid=True, xmin=-50, xmax=50, ymin=-1, ymax=1, **graph_theme) """ c = next(colors) print(c) plot = SmoothLinePlot(color=c) plot.points = [(x / 10., sin(x / 50.)) for x in range(-500, 501)] # for efficiency, the x range matches xmin, xmax graph.add_plot(plot) """ plot = MeshLinePlot(color=next(colors)) plot.points = [(x / 10., cos(x / 50.)) for x in range(-500, 501)] graph.add_plot(plot) self.plot = plot # this is the moving graph, so keep a reference """ plot = MeshStemPlot(color=next(colors)) graph.add_plot(plot) plot.points = [(x, x / 50.) for x in range(-50, 51)] """ plot = BarPlot(color=next(colors), bar_spacing=.72) graph.add_plot(plot) plot.bind_to_graph(graph) plot.points = [(x, .1 + randrange(10) / 10.) for x in range(-50, 1)] # Test the scatter plot plot = ScatterPlot(color=next(colors), point_size=5) graph.add_plot(plot) plot.points = [(x, .1 + randrange(10) / 10.) for x in range(-50, 1)] Clock.schedule_interval(self.update_points, 1 / 60.) graph2 = Graph( xlabel='Position (m)', ylabel='Time (s)', x_ticks_minor=0, x_ticks_major=1, y_ticks_major=10, y_grid_label=True, x_grid_label=True, padding=5, xlog=False, ylog=False, xmin=0, ymin=0, **graph_theme) b.add_widget(graph) if np is not None: (xbounds, ybounds, data) = self.make_contour_data() # This is required to fit the graph to the data extents graph2.xmin, graph2.xmax = xbounds graph2.ymin, graph2.ymax = ybounds plot = ContourPlot() plot.data = data plot.xrange = xbounds plot.yrange = ybounds plot.color = [1, 0.7, 0.2, 1] graph2.add_plot(plot) b.add_widget(graph2) self.contourplot = plot Clock.schedule_interval(self.update_contour, 1 / 60.) return b def make_contour_data(self, ts=0): omega = 2 * pi / 30 k = (2 * pi) / 2.0 ts = sin(ts * 2) + 1.5 # emperically determined 'pretty' values npoints = 100 data = np.ones((npoints, npoints)) position = [ii * 0.1 for ii in range(npoints)] time = [(ii % 100) * 0.6 for ii in range(npoints)] for ii, t in enumerate(time): for jj, x in enumerate(position): data[ii, jj] = sin( k * x + omega * t) + sin(-k * x + omega * t) / ts return (0, max(position)), (0, max(time)), data def update_points(self, *args): self.plot.points = [ (x / 10., cos(Clock.get_time() + x / 50.)) for x in range(-500, 501)] def update_contour(self, *args): _, _, self.contourplot.data[:] = self.make_contour_data( Clock.get_time()) # this does not trigger an update, because we replace the # values of the arry and do not change the object. # However, we cannot do "...data = make_contour_data()" as # kivy will try to check for the identity of the new and # old values. In numpy, 'nd1 == nd2' leads to an error # (you have to use np.all). Ideally, property should be patched # for this. self.contourplot.ask_draw() TestApp().run()