Is there a way to display a pandas Dataframe in KivyMD? - python-3.x

Is there a way to display a pandas DataFrame in KivyMD? I tried putting the dataframe as a KivyMD DataTable but it doesn't work that way.

You could use the MDDataTable and fill the row with the dataframe. You only need to process the data. Try to define a function to do that:
def get_data_table(dataframe):
column_data = list(dataframe.columns)
row_data = dataframe.to_records(index=False)
return column_data, row_data
Then you can put all into the MDDataTable after setting the size of columns.
import pandas as pd
from kivy.uix.anchorlayout import AnchorLayout
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivymd.uix.datatables import MDDataTable
from kivy.metrics import dp
dataframe = pd.read_csv(filename)
class MyApp(MDApp):
def build(self):
layout = AnchorLayout()
container = my_root.ids.container
print(container)
column_data, row_data = get_data_table(dataframe)
column_data = [(x, dp(60)) for x in column_data]
table = MDDataTable(
column_data = column_data,
row_data = row_data,
use_pagination=True
)
layout.add_widget(table)
return layout
MyApp().run()

Related

Difficults with groupby() and both Bokeh figure()

I don't know exactly where but I believe that I haven't assign the data to the figure, any help please to drag these data from the limbo back to the figure?
from bokeh.plotting import figure, output_notebook, show
import numpy as np
import pandas as pd
from bokeh.models import ColumnDataSource
from bokeh.colors import RGB
from bokeh.sampledata.autompg2 import autompg2 as data
data = pd.read_csv('auto-mpg2.csv', thousands=',', index_col='class')
output_notebook()
print(data.dtypes)
dataHeads = data.head()
group = data[100:150].groupby('class')
group1 = data[100:150].groupby('cty')
source = ColumnDataSource(group, group1)
#dataHeads
#yA = dataU.loc['a4']
#dataU.loc['malibu'].cty
p = figure(plot_height=500, plot_width=1200, x_range=group, title='City
MPG vs Class MPG',
x_axis_label='Class', y_axis_label='MPG')
p.vbar(x=index, top=index, width=0.9, color ='#35B778', source=source)
show(p)
Do you mean something like this?
from bokeh.plotting import figure, output_notebook, show
import numpy as np
import pandas as pd
from bokeh.models import ColumnDataSource
from bokeh.colors import RGB
from bokeh.sampledata.autompg2 import autompg2 as data
df = pd.DataFrame(data)
source = ColumnDataSource(df)
group = data[100:150].groupby('class')
p = figure(plot_height = 500, plot_width = 1200, x_range = group, title = 'City MPG vs Class MPG',
x_axis_label = 'Class', y_axis_label = 'MPG')
p.vbar(x = 'class', top = 'cty', width = 0.9, color = '#35B778', source = source)
show(p)

Trouble loading csv data into bokeh

I am having trouble loading data from a csv file into bokeh, from bokeh database it works, though when I try from a csv file it does not load, so I had been reading but no luck so far.
Thanks in advance
df = pd.read_csv('unemployment1948.csv', delimiter = ',', index_col =
'Year')
df = pd.DataFrame(df)
df.head()
output_notebook()
group = df[35:].groupby('Year')
source = ColumnDataSource(df)
group.describe()
df.columns
#source = ColumnDataSource(df(x=df.loc[15:40].index,
# y=df.loc[15:40].Annual))
p = figure(plot_height=300, plot_width=900, x_range=group,
title='Umployment over the years',
x_axis_label='Year', y_axis_label='Annual')
p.circle(x=index, y='Annual', width=0.9, color ='#35B778' , source=source)
show(p)
Your df is already a pandas DataFrame. Try this:
import os
import pandas as pd
from bokeh.io import show
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
df = pd.read_csv(os.path.join(os.path.dirname(__file__), "unemployment1948.csv",))
output_notebook()
source = ColumnDataSource(df)
p = figure(plot_height = 300, plot_width = 900,
title = 'Umployment over the years',
x_axis_label = 'Year', y_axis_label = 'Annual')
p.circle(x = 'Year', y = 'Annual', line_width = 0.9, color = '#35B778' , source = source)
show(p)
I learned how to deal with DataFrame and ColumnDateSource, so you can manipulate the data easily and it does not need to use the OS module.
Thanks for the help.
import csv
#import re
import pandas as pd
import numpy as np
#import random
##from collections import Counter, defaultdict
#import random
dfU = pd.read_csv('unemployment1948.csv')
dfU = pd.DataFrame(dfU)
dfU.index
y = dfU.iloc[35:].Year
x = dfU.iloc[35:].Annual
#xRange = dfU.iloc[35:]
source = ColumnDataSource(dfU)
output_notebook()
p = figure(plot_height=300, plot_width=800, title='Unemployment over the years')
p.vbar(x='Year', top='Annual', width=0.9, color ='#35B778' , source=source)
show(p)

Why won't bokeh figure update with new data?

I'm creating a bokeh application that pulls data from Quandl stock prices and changes the plot based the stock symbol the user inputs. I used an example from this bokeh tuorial as a model.
Everything is working except the plot won't update when I input a new symbol.
I've tried passing the new data as a dictionary (before I was just passing a DataFrame to ColumnDataSource(), but no luck.
import pandas as pd
import numpy as np
from bokeh.models.widgets import TextInput, Select
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.layouts import column, row
from bokeh.io import show, output_notebook
import quandl
This is the function to get the data:
def get_data(symbol):
dictionary = {}
data = quandl.get('WIKI/' + symbol, collapse = 'annual', returns='numpy')
df = pd.DataFrame(data)
dictionary['date'] = list(df.Date.values)
dictionary['high'] = list(df.High.values)
return dictionary
And this is a function for the plot:
def modify_doc(doc):
symbol = 'AAWW'
source = ColumnDataSource(data = get_data(symbol))
p = figure(x_axis_type='datetime', title='Stock Price', plot_height=350, plot_width=800)
p.xgrid.grid_line_color=None
p.ygrid.grid_line_alpha=0.5
p.xaxis.axis_label = 'year'
p.yaxis.axis_label = 'close'
r = p.line(source.data['date'],
source.data['high'],
line_color = 'navy')
select = Select(title="Color", value="navy", options=COLORS)
input = TextInput(title="Ticker Symbol", value=symbol)
def update_symbol(attrname, old, new):
source.data = get_data(input.value)
input.on_change('value', update_symbol)
layout = column(row(input, width=400), row(p))
doc.add_root(layout)
show(modify_doc)
I would think that the plot would update when the new symbol is entered, but it just stays the same.
Any thoughts?
Your code looks like Bokeh server application but you use show() what doesn't look good to me. You are also trying to update the figure by assigning new data to the source but you did not pass your source to the figure object so it won't have any effect. Could you try if this code works for you? (should work for Bokeh v1.0.4)
import random
import pandas as pd
from tornado.ioloop import IOLoop
from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource
from bokeh.models.widgets import TextInput
from bokeh.layouts import column, row
def make_document(doc):
symbol = 'AAWW'
def get_data(symbol):
dictionary = {}
data = quandl.get('WIKI/' + symbol, collapse = 'annual', returns = 'numpy')
df = pd.DataFrame(data)
dictionary['date'] = list(df.Date.values)
dictionary['high'] = list(df.High.values)
return dictionary
source = ColumnDataSource(data = get_data(symbol))
p = figure(x_axis_type = 'datetime', title = 'Stock Price', plot_height = 350, plot_width = 800)
p.xgrid.grid_line_color = None
p.ygrid.grid_line_alpha = 0.5
p.xaxis.axis_label = 'year'
p.yaxis.axis_label = 'close'
r = p.line(x = 'date',
y = 'high',
source = source,
line_color = 'navy')
input = TextInput(title = "Ticker Symbol", value = symbol)
def update_symbol(attrname, old, new):
source.data = get_data(input.value)
input.on_change('value', update_symbol)
layout = column(row(input, width = 400), row(p))
doc.add_root(layout)
io_loop = IOLoop.current()
server = Server({'/myapp': Application(FunctionHandler(make_document))}, port = 5001, io_loop = io_loop)
server.start()
server.show('/myapp')
io_loop.start()
Basically the main change is here:
r = p.line(x = 'date',
y = 'high',
source = source,
line_color = 'navy')
Based on the answer I got from Tony, I just had to change one line of code:
r = p.line(x = 'date',
y = 'high',
source = source,
line_color = 'navy')

how to push live panda Dataframe and index it to fit it in my Tkinter table?

I am trying to push my mqtt data to my tkinter table, which i have created using pandastable module. I am getting data in form of a list. So i first created a csv file, and i labeled it manually. And then i pushed my list to that csv file. So, i have two part in my table, first it will take converted dataframe from my csv file and is like the history part of table and then i need to push my recent dataframe(which is in same format as my previous dataframes with my csv file's column index as my dataframe column index ) to that table while its open. And also i am saving my recent datframes in csv file, so this process can in circle every time i open my table.Problem is i can't figure where i am going wrong.
this is my table script:
import tkinter as tk
import pandas as pd
from pandastable import Table, TableModel
from threading import Thread
import time
import datetime
import numpy as np
#import mqtt_cloud_rec
#import tkintermqtt
prevframe = pd.read_csv('mqttresult.csv')
class TestApp(tk.Frame):
"""Basic test frame for the table"""
def __init__(self, parent=None):
self.parent = parent
tk.Frame.__init__(self)
self.main = self.master
self.main.geometry('800x600+200+100')
self.main.title('Mqtt Result Table')
f = tk.Frame(self.main)
f.pack(fill=tk.BOTH,expand=1)
#df = TableModel.getSampleData(rows=5)
self.table = pt = Table(f, dataframe=prevframe, showtoolbar=True )
pt.show()
self.startbutton = tk.Button(self.main,text='START',command=self.start)
self.startbutton.pack(side=tk.TOP,fill=tk.X)
self.stopbutton = tk.Button(self.main,text='STOP',command=self.stop)
self.stopbutton.pack(side=tk.TOP,fill=tk.X)
# self.table.showPlotViewer()
return
def update(self,data):
table=self.table
#plotter = table.pf
#opts = plotter.mplopts
#plotter.setOption('linewidth',3)
#plotter.setOption('kind','line')
#opts.widgets['linewidth'].set(3)
#opts.widgets['kind'].set('line')
date_today=str(datetime.date.today())
time_today=time.strftime("%H:%M:%S")
datalist=[date_today,time_today]+self.data
datalist1=np.array(datalist)
datalist2=pd.DataFrame(data=datalist1 ,columns=['Date','Time','power state','Motor state','Mode','Voltage','Current','Power Factor','KW','KWH','total Runtime'])
#self.table = Table(dataframe=datalist2, showtoolbar=True )
self.dataframe.loc[len(self.dataframe)]=datalist2
table.model.df=self.dataframe
table.redraw()
#table.multiplecollist=range(0,10)
#table.plotSelected()
time.sleep(.1)
if self.stop == True:
return
return
def start(self):
self.stop=False
t = Thread(target=self.update)
t.start()
def stop(self):
self.stop = True
return
app = TestApp()
#launch the app
app.mainloop()
Convert this to a dictionary instead of a Dataframe and I think it will work:
datalist=[date_today,time_today]+self.data
datalist1=np.array(datalist)
datalist2=pd.DataFrame(data=datalist1 ,columns=['Date','Time','power state','Motor state','Mode','Voltage','Current','Power Factor','KW','KWH','total Runtime'])

How to select a particular csv file and plot the graph from the multiple csv files folder using browser button in python

How I can select a particular csv file from a folder which contains 'n' number of csv files and all csv files are of the same kind with 3 columns only the values are different. So, my aim is to select a single csv file by clicking the browser button and then the graph should get plotted with the selection I made.
Sample csv file points
z,x,y
23,0,0
23,0.05387,6.66634
23,0.11799,13.787
23,0.19989,22.9338
23,0.3072,35.0772
23,0.56904,63.648
23,0.84889,91.5284
23,1.22228,123.65
23,1.72457,156.606
23,1.95494,167.717
23,2.25261,178.844
23,2.59162,186.982
23,2.91377,190.805
23,3.23132,190.89
120,0,0
120,0.08749,5.44471
120,0.16471,9.48296
120,0.31905,16.8751
120,0.82326,37.8111
120,1.45144,56.0784
120,2.24965,72.0364
120,3.01642,82.2629
120,3.82591,89.1323
120,4.91071,94.4476
120,6.15553,97.6881
120,7.45795,99.0951
120,8.31468,98.7398
160,0,0
160,0.1142,5.59709
160,0.24587,10.7453
160,0.77917,27.9152
160,1.50412,42.5702
160,2.4017,53.905
160,3.49796,62.7076
160,4.77411,69.3479
160,6.24681,74.2705
160,7.93673,77.5658
160,9.78794,79.1005
160,10.1071,78.9901
I have written a code but with my code I always need to change the 'filename'
in the 'filename.csv' and then need to select from the browser according to filename. I want to make it easy without changing the filename any csv file can be selected.
from tkinter import *
import csv
import os
import tkinter as tk
import sys
from tkinter import filedialog
import pandas as pd
import matplotlib.pyplot as plt
import math
#from sympy import *
from tkinter import ttk
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self,master)
self.grid()
self.createWidgets()
def createWidgets(self):
top = self.winfo_toplevel()
self.menuBar = Menu(top)
top["menu"] = self.menuBar
self.subMenu = Menu(self.menuBar)
self.menuBar.add_cascade(label = "File", menu = self.subMenu)
self.subMenu.add_command( label = "Read Data",command = self.readCSV)
def readCSV(self):
x=[]
y=[]
z=[]
self.filename = filedialog.askopenfilename()
df=pd.read_csv('GF30.csv', error_bad_lines=False)
read = csv.reader(df, delimiter = ",")
fig = plt.figure()
data_list = []
ax= fig.add_subplot(111)
buttons = next(read)
df.set_index('x', inplace=True)
df.groupby('z')['y'].plot(legend=True,ax=ax)
leg = ax.legend(bbox_to_anchor = [1.1, 0.7], fancybox=True, shadow=True)
leg.get_frame().set_alpha(0.4)
plt.show()
print
for btn in buttons:
new_btn = Button(self, text="btn", command = self.btnClick)
new_btn.pack()
self.root.mainloop()
def btnClick(self):
root.destroy()

Resources