How can I plot a dataframe bar-graph using pandas in tkinter? - pandas

I am trying to plot a dataframe graph in tkinter , such that it is ploted in the window of the application.
My code is :
import tkinter as tk
from tkinter import ttk, Canvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import pandas as pd
class application():
def __init__(self):
self.win = tk.Tk()
self.win.title('Emetor')
self.win.geometry('700x650+230+30')
self.win.configure(background='pale green')
self.createWidgets()
def createWidgets(self):
self.var1 = tk.IntVar()
self.check1 = tk.Checkbutton(self.win, text='1',command= self.mat, variable=self.var1)
self.check1.grid(row=1,column=0)
def mat(self):
data=[{'a':1,'b':2},{'a':1,'b':4},{'a':1,'b':6},{'a':1,'b':8}]
index=['1','2','3','4']
fig=Figure(figsize=(4,5), facecolor='white')
a=fig.add_subplot(111)
df = pd.DataFrame(data, index=index)
df.plot(kind='bar')
plt.show()
canvas=FigureCanvasTkAgg(fig, self.win)
canvas.get_tk_widget().grid(row=1, column=0, columnspan=4)
canvas.show()
if __name__ == '__main__':
app = application()
app.win.mainloop()
and the result is :
dataframe bar graph
If someone has any idea how to make the figure show in the main widow not in a seperated one, it would be a great help for me .
Thank you :)

Related

Creating 3D scatter chart in Taipy

I was wondering how one would create a 3D scatter chart in Taipy.
I tried this code initially:
import pandas as pd
import numpy as np
from taipy import Gui
df = pd.DataFrame(np.random.randint(0,100,size=(100, 3)), columns=list('xyz'))
df['cluster1']=np.random.randint(0,3,100)
my_page ="""
Creation of a 3-D chart:
<|{df}|chart|type=Scatter3D|x=x|y=y|z=z|mode=markers|color=cluster|>
"""
Gui(page=my_page).run()
This does indeed display a 3D plot, but the colors (clusters) do not show up.
Any hint?
Yes, you need some massaging of your dataframes to do it.
Here's a sample code that achieves this:
import pandas as pd
import numpy as np
from taipy import Gui
df = pd.DataFrame(np.random.randint(0,100,size=(100, 3)), columns=list('xyz'))
df['cluster1']=np.random.randint(0,3,100)
# Create a list of 3 dataframes, one per cluster
datas = [df[df['cluster1']==i] for i in range(3)]
properties = {
}
# create dynamically the property list.
# str(i) points to a dataframe index
# "/x" points to the column value in the selected dataframe
for i in range(len(datas)):
properties[f"x[{i+1}]"] = str(i)+"/x"
properties[f"y[{i+1}]"] = str(i)+"/y"
properties[f"z[{i+1}]"] = str(i)+"/z"
properties[f'name[{i+1}]'] = str(i+1)
print(properties)
chart = "<|{datas}|chart|type=Scatter3D|properties={properties}|mode=markers|height=800px|>"
Gui(page=chart).run()
In fact, with the new release: Taipy 1.1, this is very easy to do in a few lines of code:
import pandas as pd
import numpy as np
from taipy import Gui
color_map={0:"blue",1:'green', 2:"red"}
df = pd.DataFrame(np.random.randint(0,100,size=(100, 3)), columns=list('xyz'))
df['cluster1'] = np.random.randint(0,3,100)
df['cluster_colors'] = df.apply(lambda row: color_map[row.cluster1], axis=1)
marker = {"color":"cluster_colors"}
chart = "<|{df}|chart|type=Scatter3D|x=x|y=y|z=z|marker={marker}|mode=markers|height=800px|>"
Gui(page=chart).run()
If you want to leave it to Taipy to pick the colors for you, then you can simply use:
import pandas as pd
import numpy as np
from taipy import Gui
df = pd.DataFrame(np.random.randint(0,100,size=(100, 3)), columns=list('xyz'))
df['cluster1'] = np.random.randint(0,3,100)
marker = {"color":"cluster1"}
chart = "<|{df}|chart|type=Scatter3D|x=x|y=y|z=z|marker={marker}|mode=markers|height=800px|>"
Gui(page=chart).run()

Why sparklines are outside of table as expected?

Bonjour,
"sparkline" does not work in my code.
Already, I didn't manage to install it. So, I found a function that I call "sparkline_test. Nevertheless, the images that should be integrated in the table are outside. Something is wrong.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from io import BytesIO
from itertools import islice
import seaborn as sns
import base64
I cannot import sparklines:
#import sparklines
df = sns.load_dataset('titanic')
def percentile_90(x):
return x.quantile(.9)
from scipy.stats import trim_mean
def trim_mean_10(x):
return trim_mean(x, 0.1)
def largest(x):
return x.nlargest(1)
def sparkline_str(x):
bins=np.histogram(x)[0]
sl = ''.join(sparklines(bins))
return sl
def sparkline_test(data, figsize=(4,0.25),**kwags):
data = list(data)
fig,ax = plt.subplots(1,1,figsize=figsize,**kwags)
ax.plot(data)
for k,v in ax.spines.items():
v.set_visible(False)
ax.set_xticks([])
ax.set_yticks([])
plt.plot(len(data)-1, data[len(data)-1], 'r.')
ax.fill_between(range(len(data)), data, len(data)*[min(data)], alpha=0.1)
img = BytesIO()
plt.savefig(img, transparent=True, bbox_inches='tight')
img.seek(0)
plt.show()
# plt.close()
return base64.b64encode(img.read()).decode("utf-8")
def sparkline_str(x):
bins=np.histogram(x)[0]
sl = ''.join(sparkline_test(bins))
return sl
agg_func_largest = {
'fare': [percentile_90, trim_mean_10, largest, sparkline_test]
#'fare': [percentile_90, trim_mean_10, largest]
}
df.groupby(['class', 'embark_town']).agg(agg_func_largest)
that produces:
What is expected is:
Something is wrong....But what?
Do you have any idea?
Regards,
Atapalou

BoxPlot figure is not showing( just getting <AxesSubplot:>)

I am already having Tkinter(someone said to install a tkinter)
code used:
imports are:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
if u want to view the data-set then it is :
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/diabetes.csv")
code used to plot boxplot in jupyter notebook
fig, ax = plt.subplots(figsize = (20,20))
sns.boxplot(data = df,ax = ax)
)
I was supposed to add in my import's
%matplotlib inline

Understanding plt.show() in Matplotlib

import numpy as np
import os.path
from skimage.io import imread
from skimage import data_dir
img = imread(os.path.join(data_dir, 'checker_bilevel.png'))
import matplotlib.pyplot as plt
#plt.imshow(img, cmap='Blues')
#plt.show()
imgT = img.T
plt.figure(1)
plt.imshow(imgT,cmap='Greys')
#plt.show()
imgR = img.reshape(20,5)
plt.figure(2)
plt.imshow(imgR,cmap='Blues')
plt.show(1)
I read that plt.figure() will create or assign the image a new ID if not explicitly given one. So here, I have given the two figures, ID 1 & 2 respectively. Now I wish to see only one one of the image.
I tried plt.show(1) epecting ONLY the first image will be displayed but both of them are.
What should I write to get only one?
plt.clf() will clear the figure
import matplotlib.pyplot as plt
plt.plot(range(10), 'r')
plt.clf()
plt.plot(range(12), 'g--')
plt.show()
plt.show will show all the figures created. The argument you forces the figure to be shown in a non-blocking way. If you only want to show a particular figure you can write a wrapper function.
import matplotlib.pyplot as plt
figures = [plt.subplots() for i in range(5)]
def show(figNum, figures):
if plt.fignum_exists(figNum):
fig = [f[0] for f in figures if f[0].number == figNum][0]
fig.show()
else:
print('figure not found')

cannot plot lines on matplotlib embedded in pyqt5

Following is the codes. It plots a line via pressing a button. However, when I pressed the button, it just printed
matplotlib.lines.Line2D object at 0x11371fcc0 ......
but could not show the line on the canvas. How do you fix it?
import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore
from PyQt5.QtWidgets import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import mywidgets
# mywidgets.MplCanvas is a wrapper of FigureCanvas in order to make the drawing convenient.
class ApplicationWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setWindowTitle("Hello")
self.main_widget = QWidget(self)
l = QVBoxLayout(self.main_widget)
fig1 = Figure(figsize=(5, 4))
self.sc = mywidgets.MplCanvas(self.main_widget, fig1)
l.addWidget(self.sc)
bdraw = QPushButton('Draw')
bdraw.pressed.connect(self.draw)
l.addWidget(bdraw)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
def draw(self):
# it does not report any error, but on lines are drawn.
line = self.sc.axes.plot([1,2,3], 'r')
print(line)
if __name__ == '__main__':
app = QApplication([])
aw = ApplicationWindow()
aw.show()
#sys.exit(qApp.exec_())
app.exec_()
You forgot to update the canvas after plotting to it.
def draw(self):
line = self.sc.axes.plot([1,2,3], 'r')
self.sc.draw_idle()