簡體   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