【问题标题】:How to add sort functionality with a Button to a Matplotlib bar plot and line plot如何使用按钮将排序功能添加到 Matplotlib 条形图和线图
【发布时间】:2021-01-09 02:13:43
【问题描述】:

我刚刚开始尝试用 Python 进行可视化。使用以下代码,我正在尝试将排序功能添加到从数据框中绘制的 Matplotlib 条形图。我想在图表上添加一个button,比如sort,这样当它被点击时,它会按照从最高销售数字到最低销售数字的顺序显示一个新的图,目前按钮可以显示但排序无法触发功能。任何想法或指针将不胜感激。

[更新尝试]

import matplotlib.pyplot as plt
from matplotlib.widgets import Button

def sort(data_frame):
    sorted = data_frame.sort_values('Sales')
    return data_frame2

def original():
   
    return data_frame

data_frame.plot.bar(x="Product", y="Sales", rot=70, title="Sales Report");
plot.xlabel('Product')
plot.ylabel('Sales')

axcut = plt.axes([0.9, 0.0, 0.1, 0.075])
bsort = Button(axcut,'Sort')
bsort.on_clicked(sort)
axcut2 = plt.axes([1.0, 0.0, 0.1, 0.075])
binit = Button(axcut2,'Original')
binit.on_clicked(original)
plt.show()

预期的图形输出

整合

import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import seaborn as sns
%matplotlib notebook

class Index(object):
        ind = 0
        global funcs
    
        def next(self, event):
            self.ind += 1
            i = self.ind %(len(funcs))
            x,y,name = funcs[i]() # unpack tuple data
            for r1, r2 in zip(l,y):
                r1.set_height(r2)
            ax.set_xticklabels(x)
            ax.title.set_text(name) # set title of graph
            plt.draw()        

class Show():
        
        def trigger(self):
            number_button = tk.Button(button_frame2, text='Trigger', command= self.sort)
        
    
        def sort(self,df_frame):
    
            fig, ax = plt.subplots()
            plt.subplots_adjust(bottom=0.2)
            
            ######intial dataframe
            df_frame
            ######sorted dataframe
            dfsorted = df_frame.sort_values('Sales')
           
    
            x, y = df_frame['Product'], df_frame['Sales']
            x1, y1 = df_frame['Product'], df_frame['Sales']
            x2, y2 = dfsorted['Product'], dfsorted['Sales']
    
            l = plt.bar(x,y)
            plt.title('Sorted - Class')
            l2 = plt.bar(x2,y1)
            l2.remove()
            
            def plot1():
                x = x1
                y = y1
                name = 'ORginal'
                return (x,y,name)
    
            def plot2():
                x = x2
                y = y2
                name = 'Sorteds'
                return (x,y,name)
            
            funcs = [plot1, plot2]        
            callback = Index()
            button = plt.axes([0.81, 0.05, 0.1, 0.075])
            bnext = Button(button, 'Sort', color='green')
            bnext.on_clicked(callback.next)
    
            plt.show()

【问题讨论】:

  • plotly / dash 更适合这个。这个问题在我看来有点太宽泛了,因为可能有很多不同的方法。
  • 好的,编辑问题以缩小焦点。我可以知道我想使用 Matplotlib/Seaborn,哪个会更好地添加排序按钮功能
  • 我会创建一个按钮,一个按钮代表默认图形,一个按钮代表排序图形。要导入使用 from matplotlib.widgets import Button 并查看此答案:stackoverflow.com/a/47384928/6366770
  • 您可以通过包含 seaborn 数据集作为示例来使您的问题可重现。 flights 是一个示例数据集,但您可以使用 sns.get_dataset_names() 探索其他数据集名称并将其中一个传递给 sns.load_dataset(),例如df = sns.load_dataset('flights')
  • 也。 import matplotlib.pyplot as plot 通常用作import matplotlib.pyplot as plt。我会改变你的语法,因为它可能会与 pandas 方法 plot 混淆

标签: python python-3.x matplotlib seaborn


【解决方案1】:

我已经包含了两个使用著名的titanic 数据集的可重现示例,以及class# of survivors 的基本比较,用于matplotlib barplot(即行)排序的交互式排序下面的x轴:

使用bar 绘图,您必须使用set_height 遍历矩形,例如for r1, r2 in zip(l,y): r1.set_height(r2)line 绘图,您使用 set_ydata,例如l.set_ydata(y).

如果使用 jupyter notebook,请确保使用%matplotlib notebook

酒吧

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import seaborn as sns
%matplotlib notebook

fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)

df = sns.load_dataset('titanic')
df1 = df.groupby('class', as_index=False)['survived'].sum().sort_values('class')
df2 = df1.sort_values('survived', ascending=False)
x, y = df1['class'], df1['survived']
x1, y1 = df1['class'], df1['survived']
x2, y2 = df2['class'], df2['survived']

l = plt.bar(x,y)
plt.title('Sorted - Class')
l2 = plt.bar(x2,y1)
l2.remove()

class Index(object):
    ind = 0
    global funcs

    def next(self, event):
        self.ind += 1
        i = self.ind %(len(funcs))
        x,y,name = funcs[i]() # unpack tuple data
        for r1, r2 in zip(l,y):
            r1.set_height(r2)
        ax.set_xticklabels(x)
        ax.title.set_text(name) # set title of graph
        plt.draw()


def plot1():
    x = x1
    y = y1
    name = 'Sorted - Class'
    return (x,y,name)


def plot2():
    x = x2
    y = y2
    name = 'Sorted - Highest # Survivors'
    return (x,y,name)


funcs = [plot1, plot2]        
callback = Index()
button = plt.axes([0.81, 0.05, 0.1, 0.075])
bnext = Button(button, 'Sort', color='green')
bnext.on_clicked(callback.next)

plt.show()

LINE

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import seaborn as sns
%matplotlib notebook

fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)

df = sns.load_dataset('titanic')
df1 = df.groupby('class', as_index=False)['survived'].sum().sort_values('class')
df2 = df1.sort_values('survived', ascending=False)
x, y = df1['class'].to_numpy(), df1['survived'].to_numpy()
x1, y1 = df1['class'].to_numpy(), df1['survived'].to_numpy()
x2, y2 = df2['class'].to_numpy(), df2['survived'].to_numpy()
l, = plt.plot(x,y)
plt.title('Sorted - Class')

class Index(object):
    ind = 0
    global funcs

    def next(self, event):
        self.ind += 1
        i = self.ind %(len(funcs))
        x,y,name = funcs[i]() # unpack tuple data
        l.set_ydata(y) #set y value data
        ax.set_xticklabels(x)
        ax.title.set_text(name) # set title of graph
        plt.draw()


def plot1():
    x = x1
    y = y1
    name = 'Sorted - Class'
    return (x,y,name)


def plot2():
    x = x2
    y = y2
    name = 'Sorted - Highest # Survivors'
    return (x,y,name)


funcs = [plot1, plot2]        
callback = Index()
button = plt.axes([0.81, 0.05, 0.1, 0.075])
bnext = Button(button, 'Sort', color='green')
bnext.on_clicked(callback.next)

plt.show()

【讨论】:

  • 请问我可以用程序化的方式实现,而不是 OOP 实现,谢谢
  • @epiphany 我从文档中改编了它,但不确定如何在没有 OOP 的情况下轻松实现它。
  • 明白了,我已经尝试以 OOP 风格实现它[在集成部分更新],Show() 类是主类,目前我会得到吧要显示图表和按钮,但未触发单击功能,似乎无法调用索引类中的下一个函数,有什么想法吗?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2020-09-10
  • 2012-01-06
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多