Python 使用Matplotlib绘制可拖动的折线

效果图: 

可以拖曲线上的点调整, 也可以拖旁边的sliderbar调整.

代码如下:

import matplotlib.animation as animation
from matplotlib.widgets import Slider, Button
import pandas as pd
import matplotlib as mpl
from matplotlib import pyplot as plt
import scipy.interpolate as inter
import numpy as np func = lambda x: np.zeros_like(x) def load_cache_weight(cache_file):
import yaml
global yvals
with open(cache_file,'r') as f:
line = f.readline()
d = dict(yaml.safe_load(line))
keys = d.keys()
for i, key in enumerate(keys):
yvals[i] = d[key] # user input config
N = 30
st = pd.to_datetime('20230414')
cache_file = None
cache_file = './tmp/saved_weight_2.json'
save_file = './tmp/saved_weight_2.json' #get a list of points to fit a spline to as well
xmin = 1
xmax = N+1
x = np.linspace(xmin,xmax,N) #spline fit
yvals = func(x)
if cache_file is not None:
load_cache_weight(cache_file)
spline = inter.InterpolatedUnivariateSpline (x, yvals) #figure.subplot.right
mpl.rcParams['figure.subplot.left'] = 0.1
mpl.rcParams['figure.subplot.right'] = 0.8 #set up a plot
fig,axes = plt.subplots(1,1,figsize=(16,5),sharex=True)
ax1 = axes pind = None #active point
epsilon = 5 #max pixel distance def update(val):
global yvals
global spline
# update curve
for i in np.arange(N):
yvals[i] = sliders[i].val
l.set_ydata(yvals)
spline = inter.InterpolatedUnivariateSpline(x, yvals)
m.set_ydata(spline(X))
# redraw canvas while idle
fig.canvas.draw_idle() def reset(event):
global yvals
global spline
#reset the values
yvals = func(x)
if cache_file is not None:
load_cache_weight(cache_file)
for i in np.arange(N):
sliders[i].reset()
spline = inter.InterpolatedUnivariateSpline(x, yvals)
l.set_ydata(yvals)
m.set_ydata(spline(X))
# redraw canvas while idle
fig.canvas.draw_idle() def save_p(event):
global yvals
global datelst
global save_file
r = dict(zip(map(lambda x: x.strftime('%Y%m%d'),datelst),yvals))
print(r)
if save_file is not None:
with open(save_file,'w') as f:
import json
json.dump(r,f) def button_press_callback(event):
'whenever a mouse button is pressed'
global pind
if event.inaxes is None:
return
if event.button != 1:
return
#print(pind)
pind = get_ind_under_point(event) def button_release_callback(event):
'whenever a mouse button is released'
global pind
if event.button != 1:
return
pind = None def get_ind_under_point(event):
'get the index of the vertex under point if within epsilon tolerance' # display coords
#print('display x is: {0}; display y is: {1}'.format(event.x,event.y))
t = ax1.transData.inverted()
tinv = ax1.transData
xy = t.transform([event.x,event.y])
#print('data x is: {0}; data y is: {1}'.format(xy[0],xy[1]))
xr = np.reshape(x,(np.shape(x)[0],1))
yr = np.reshape(yvals,(np.shape(yvals)[0],1))
xy_vals = np.append(xr,yr,1)
xyt = tinv.transform(xy_vals)
xt, yt = xyt[:, 0], xyt[:, 1]
d = np.hypot(xt - event.x, yt - event.y)
indseq, = np.nonzero(d == d.min())
ind = indseq[0] #print(d[ind])
if d[ind] >= epsilon:
ind = None #print(ind)
return ind def motion_notify_callback(event):
'on mouse movement'
global yvals
if pind is None:
return
if event.inaxes is None:
return
if event.button != 1:
return #update yvals
#print('motion x: {0}; y: {1}'.format(event.xdata,event.ydata))
yvals[pind] = np.clip(event.ydata,-1,1) # update curve via sliders and draw
sliders[pind].set_val(yvals[pind])
fig.canvas.draw_idle() ############################ ed = st+pd.Timedelta(days=N-1)
datelst = pd.date_range(st,ed) # ax1.plot () ########################### X = np.arange(0,xmax+1,0.1)
ax1.plot (X, func(X), 'k--', label='original')
l, = ax1.plot (x,yvals,color='k',linestyle='none',marker='o',markersize=8)
m, = ax1.plot (X, spline(X), 'r-', label='spline') ax1.set_yscale('linear')
ax1.set_xlim(0, 32)
ax1.set_ylim(-1.05,1.05)
ax1.set_xlabel('dt')
ax1.set_ylabel('p')
ax1.grid(True)
ax1.yaxis.grid(True,which='minor',linestyle='--')
ax1.legend(loc=2,prop={'size':8}) sliders = []
for i in np.arange(N): axamp = plt.axes([0.84, 0.95-(i*0.03), 0.12, 0.02])
# Slider
date_i = datelst[i]
mth = date_i.month
day = date_i.day
s = Slider(axamp, '{}/{}'.format(mth,day), -1, 1, valinit=yvals[i])
sliders.append(s) for i in np.arange(N):
#samp.on_changed(update_slider)
sliders[i].on_changed(update) axres = plt.axes([0.84, 0.95-((N)*0.03), 0.06, 0.02])
bres = Button(axres, 'Reset')
bres.on_clicked(reset) axres = plt.axes([0.84+0.08, 0.95-((N)*0.03), 0.06, 0.02])
bres2 = Button(axres, 'Save')
bres2.on_clicked(save_p) fig.canvas.mpl_connect('button_press_event', button_press_callback)
fig.canvas.mpl_connect('button_release_event', button_release_callback)
fig.canvas.mpl_connect('motion_notify_event', motion_notify_callback) plt.show()

Python 使用Matplotlib绘制可拖动的折线的更多相关文章

  1. Python——使用matplotlib绘制柱状图

    Python——使用matplotlib绘制柱状图 1.基本柱状图           首先要安装matplotlib(http://matplotlib.org/api/pyplot_api.htm ...

  2. python使用matplotlib绘制折线图教程

    Matplotlib是一个Python工具箱,用于科学计算的数据可视化.借助它,Python可以绘制如Matlab和Octave多种多样的数据图形.下面这篇文章主要介绍了python使用matplot ...

  3. Python使用matplotlib绘制三维曲线

    本文主要演示如何使用matplotlib绘制三维图形 代码如下: # -*- coding: UTF-8 -*- import matplotlib as mpl from mpl_toolkits. ...

  4. python包matplotlib绘制图像

    使用matplotlib绘制图像 import matplotlib.pyplot as plt from matplotlib.pyplot import MultipleLocator impor ...

  5. 【Python】matplotlib绘制折线图

    一.绘制简单的折线图 import matplotlib.pyplot as plt squares=[1,4,9,16,25] plt.plot(squares) plt.show() 我们首先导入 ...

  6. Python 使用 matplotlib绘制3D图形

    3D图形在数据分析.数据建模.图形和图像处理等领域中都有着广泛的应用,下面将给大家介绍一下如何在Python中使用 matplotlib进行3D图形的绘制,包括3D散点.3D表面.3D轮廓.3D直线( ...

  7. Python:matplotlib绘制线条图

    线型图是学习matplotlib绘图的最基础案例.我们来看看具体过程:  下面我们将两条曲线绘制到一个图形里:   可以看到这种方式下,两个线条共用一个坐标轴,并且自动区分颜色. plot方法的核心是 ...

  8. 广义mandelbrot集,使用python的matplotlib绘制,支持放大缩小

    迭代公式的指数,使用的1+5j,这是个复数.所以是广义mandelbrot集,大家能够自行改动指数,得到其它图形.各种库安装不全的,自行想办法,能够在这个站点找到差点儿全部的python库 http: ...

  9. Python:matplotlib绘制直方图

    使用hist方法来绘制直方图:     绘制直方图,最主要的是一个数据集data和需要划分的区间数量bins,另外你也可以设置一些颜色.类型参数: plt.hist(np.random.randn(1 ...

  10. Python:matplotlib绘制散点图

    与线型图类似的是,散点图也是一个个点集构成的.但不同之处在于,散点图的各点之间不会按照前后关系以线条连接起来. 用plt.plot画散点图     奇怪,代码和前面的例子差不多,为什么这里显示的却是散 ...

随机推荐

  1. SQL Server实战四:查询数据库的数据

      本文介绍基于Microsoft SQL Server软件,实现数据库表中多种数据查询方法的具体操作. 目录 1 指定列或全部列查询--查询S表学生记录 2 指定列或全部列查询--查询学生姓名与出生 ...

  2. C#/C++ 通过ODBC连接OceanBase Oracle租户

    概述 近期我们项目正处于将Oracle数据库迁移到OceanBase Oracle租户模式的阶段.考虑到我们项目采用了C++和C#混合开发,并且使用了多种技术,因此存在多种数据库连接方式.然而,针对C ...

  3. jfarme

    import java.awt.Color;import java.awt.Container; import javax.swing.JFrame;import javax.swing.JLabel ...

  4. 荒岛野人Savage

    题目描述 样例 3 1 3 4 2 7 3 3 2 1 6 分析 首先,我们先设4个变量,初始坐标 \(d[i]\),每年步数 \(p[i]\),寿命 \(l[i]\),根据题目很容易得到一个不等式 ...

  5. 使用自定义lua解析管理器调用lua脚本中的table

    [5] 使用自定义lua解析管理器调用table 访问数组类型的table CallLuaEntrance测试脚本中内容: //------------------------------------ ...

  6. Linux上执行内存中的脚本和程序

    在Linux中可以不需要有脚本或者二进制程序的文件在文件系统上实际存在,只需要有对应的数据在内存中,就有办法执行这些脚本和程序. 原理其实很简单,Linux里有办法把某块内存映射成文件描述符,对于每一 ...

  7. Selenium4自动化测试6--控件获取数据--下拉框级联选择、checkbox选择、时间选择器

    4-下拉框级联选择 import time from selenium.webdriver.support.select import Select #pip install selenium fro ...

  8. flask3之CBV和session

    flask的CBV CBV书写案例 from flask import Flask app=Flask(__name__) #FBA @app.route("/") def ind ...

  9. Python:global、local与nonlocal变量

    1 local和global变量 先来看一个最简单的Python程序例子: import numpy as np n = 2 def func(a): b = 1 return a + b print ...

  10. Java的深浅拷贝认识

    目录 浅拷贝 深拷贝 分辨代码里的深浅拷贝 在Java中,深拷贝和浅拷贝是对象复制的两种方式,主要区别在于对对象内部的引用类型的处理上. 浅拷贝 定义: 浅拷贝是指创建一个新的对象,但这个新对象的属性 ...