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. 使用 Kafka Assistant,为您的开发加速

    简要介绍 快速查看所有 Kafka 集群,包括Brokers.Topics和Consumers 支持各种认证模式:PLAINTEXT.SASL_PLAINTEXT.SSL.SASL_SSL 对Kafk ...

  2. 《Effective C++》第三版-0. 导读(Introduction)

    目录 术语(Terminology) 命名习惯(Naming Conventions) 关于线程(Threading Consideration) TR1和Boost 术语(Terminology) ...

  3. Java 泛型,这次面试我表现很棒!

    public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryBy ...

  4. DNS(4) -- dns功能实现-配置正向解析和反向解析以及DNS递归查询示例

    目录 1 DNS配置示例 1.1 DNS解析类型 1.2 配置正向解析 1.3 配置反向解析 1.4 DNS递归查询 1.4.1 开启递归查询 1.4.2 关闭递归查询 1 DNS配置示例 1.1 D ...

  5. WPF 稳定的全屏化窗口方法

    本文来告诉大家在 WPF 中,设置窗口全屏化的一个稳定的设置方法.在设置窗口全屏的时候,经常遇到的问题就是应用程序虽然设置最大化加无边框,但是此方式经常会有任务栏冒出来,或者说窗口没有贴屏幕的边.本文 ...

  6. 4G EPS 中的小区搜索

    目录 文章目录 目录 前文列表 小区搜索(Cell Search)流程 PSS(主同步信号)与 SSS(辅同步信号) DL-RS(下行参考信号) PBCH(物理广播信道) PDSCH(物理下行共享信道 ...

  7. UnityShader数学基础篇

    Mathf Mathf和Math 1.Math是C#中封装好的用于数学计算的工具类,位于System命名空间中. 2.Mathf是Unity中封装好的用于数学计算的工具结构体,位于UnityEngin ...

  8. java学习之旅(day.05)

    switch多选择结构 多选择结构还有一个实现方式就是switch case switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支 switch(expression ...

  9. PasteSpider之appsettings.json中的Serilog的配置,分流不同日志层级的信息!

    在实际使用Serilog中,我们通常会有不一样的需求,常见的比如 1.按照等级,高级哪个等级的才记录 2.记录文件每个多大,超过的划分到下一个文件中 3.不同等级的记录到不同的位置中 4.按照不一样的 ...

  10. Authentication failed. Some common reasons include:

    问题无论是pull.clone还是push都报错 fatal: Out of memory, malloc failed (tried to allocate 301989888 bytes)fata ...