繁体   English   中英

How to insert a slicer in a scatter plot 可以调整以过滤散点中的计算 plot

[英]How to insert a slicer in a scatter plot that can be adjusted to filter calculations in the scatter plot

我有散点图 plot 的数据和代码,如下所示:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# define X and y
np.random.seed(10)
x = np.arange(0,100)
y = np.random.randint(0,100,100)


df = pd.DataFrame(dict(x=x, y=y))


def dist(x,y):
    p1=np.array([0,0])
    p2=np.array([100,100])
    p3=np.array([x,y])
    return abs(np.cross(p2-p1,p3-p1)/np.linalg.norm(p2-p1))

max_dist = dist(0,10)

df["within_boundary"] = df.apply(lambda row: dist(row["x"], row["y"])<=max_dist, axis=1)

fig = plt.figure(dpi=100,figsize=(8,8))
ax = fig.subplots(1)

p0 = ax.scatter(x,y,c=df["within_boundary"]) # points
p1 = ax.plot([0,100],[0,100],'-',color="red")  # middle line
p2, = ax.plot([0,90],[10,100],'--',color="black")  # upper line
p3, = ax.plot([10,100],[0,90],'--',color="black")  # lower line
plt.xticks(np.arange(0,101,10))
plt.yticks(np.arange(0,101,10))
plt.grid(True)
plt.xlim([0,100])
plt.ylim([0,100])
percentage =df['within_boundary'].sum() / len(x)
plt.figtext(0.5,0.01, f"{percentage:.1%} in Spec", ha="center", va="center", fontsize=18, bbox={"facecolor":"grey", "alpha":0.5})
plt.show() # show the window"

我用它来生成散点图 plot,如下所示:

在此处输入图像描述

公差区域在 +-10 内,17% 的 In Spec 是 10 区域内的点数除以 plot 中的总点数。

但是我想要一个切片器,我可以使用它来过滤 plot 以从 10 区域更改为 15、20、25 等,甚至回到 10,它仍然会在该区域时自动计算 In Spec 百分比在切片器上调整为 10、15、20 或任何我想要的值,并且如果我将切片器设置为 15 或 20 等,还可以使区域线自动从 15、20 等开始运行。

Matplotlib Slider 演示已经提供了一个很好的例子。

以下示例以您的代码为基础,根据由 slider 值定义的选定容差动态更新数据。

在此处输入图像描述

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button

def dist(x,y):
    p1=np.array([0,0])
    p2=np.array([100,100])
    p3=np.array([x,y])
    return abs(np.cross(p2-p1,p3-p1)/np.linalg.norm(p2-p1))

# define X and y
np.random.seed(10)
x = np.arange(0,100)
y = np.random.randint(0,100,100)
df = pd.DataFrame(dict(x=x, y=y))

tol0 = 10 #default tolerance
max_dist = dist(0,tol0)
df["within_boundary"] = df.apply(lambda row: dist(row["x"], row["y"])<=max_dist, axis=1)

# plot definition
fig = plt.figure(dpi=100,figsize=(8,8))
ax = fig.subplots(1)
plt.subplots_adjust(bottom=0.25)
plt.xticks(np.arange(0,101,10))
plt.yticks(np.arange(0,101,10))
plt.grid(True)
plt.xlim([0,100])
plt.ylim([0,100])

# initial plotting
p0 = ax.scatter(x,y,c=df["within_boundary"]) # points
p1 = ax.plot([0,100],[0,100],'-',color="red")  # middle line
p2, = ax.plot([0,90],[10,100],'--',color="black")  # upper line
p3, = ax.plot([10,100],[0,90],'--',color="black")  # lower line

percentage = df['within_boundary'].sum() / len(x)
figtext = plt.figtext(0.5,0.01, f"{percentage:.1%} in Spec", ha="center", va="center", fontsize=18, bbox={"facecolor":"grey", "alpha":0.5})

# tolerance slider
axtol = plt.axes([0.1, 0.1, 0.8, 0.05])
stol = Slider(ax=axtol, label='Tolerance', valmin=5, valmax=50, valstep=5,valinit=tol0)
def update(val):
    # current tolerance value
    tol = stol.val

    # update data according to tolerance
    max_dist = dist(0,tol)
    df["within_boundary"] = df.apply(lambda row: dist(row["x"], row["y"])<=max_dist, axis=1)
    percentage = df['within_boundary'].sum() / len(x)
    figtext.set_text(f"{percentage:.1%} in Spec")
    p0.set_array(df["within_boundary"])
    p2.set_data([0, 100-tol], [tol,100])
    p3.set_data([tol, 100], [0,100-tol])
    fig.canvas.draw_idle()
stol.on_changed(update)

# reset button
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', hovercolor='0.975')
def reset(event):
    stol.reset()
button.on_clicked(reset)


plt.show()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM