python 桌面软件开发-matplotlib画图鼠标缩放拖动

继上一篇在 Java 中缩放拖动图片后,在python matplotlib中也来实现一个自由缩放拖动的例子:

python matplotlib 中缩放,较为简单,只需要通过设置要显示的 x y坐标的显示范围即可。基于此,实现一个鼠标监听回调,在回调中计算滚轮缩放或者鼠标拖动之后的坐标范围,即可。

效果:


上代码:

import matplotlib.pyplot as plt
import matplotlib as mpl

from matplotlib.text import Text, Annotation
from matplotlib.patches import Polygon, Rectangle, Circle, Arrow, ConnectionPatch,Ellipse,FancyBboxPatch
from matplotlib.widgets import Button, Slider, Widget

# https://www.python100.com/html/85915.html
# patches 是matplotlib里面的一个库,里面有基本图形绘制, Polygon:多边形  Rectangle:矩形  Circle:圆  Arrow:箭头 ConnecctionPatch:链接线  Ellipse:椭圆

fig = plt.figure()
ax = fig.add_subplot(111)
 
rect = Rectangle((0.1,0.1),1,1,color='yellow')
ax.add_patch(rect)

rect2 = Circle((1.5,1.5),0.2,color='red')
ax.add_patch(rect2)

arrow = ConnectionPatch((1,3),(1.8,1.8), "data", "data", clip_on=True,
                    arrowstyle="-|>", shrinkA=5, shrinkB=5, mutation_scale=20, fc="w")
arrow.set_annotation_clip(False)
ax.add_patch(arrow)

fancybox = FancyBboxPatch((2,2),width=1,height=1, boxstyle=mpl.patches.BoxStyle("Round", pad=0.2),color='green')
ax.add_patch(fancybox)

ax.text(2, 0.2, 'Hello World')

startx=0
starty=0
mPress=False
def call_move(event):
    # print(event.name)
    global mPress
    global startx
    global starty
    # print(mPress)
    if event.name=='button_press_event':
        axtemp=event.inaxes
        if axtemp and event.button==1:
            print(event)
            mPress=True
            startx=event.xdata
            starty=event.ydata
    elif event.name=='button_release_event':
        axtemp=event.inaxes
        if axtemp and event.button==1:
            mPress=False
    elif event.name=='motion_notify_event':
        axtemp=event.inaxes
        if axtemp and event.button==1 and mPress:
            x_min, x_max = axtemp.get_xlim()
            y_min, y_max = axtemp.get_ylim()
            w=x_max-x_min
            h=y_max-y_min
            # print(event)
            # 移动
            mx=event.xdata-startx
            my=event.ydata-starty
            # 注意这里, -mx,  因为下一次 motion事件的坐标,已经是在本次做了移动之后的坐标系了,所以要体现出来
            # startx=event.xdata-mx  startx=event.xdata-(event.xdata-startx)=startx, 没必要再赋值了
            # starty=event.ydata-my
            # print(mx,my,x_min,y_min,w,h)
            axtemp.set(xlim=(x_min-mx, x_min-mx+w))
            axtemp.set(ylim=(y_min-my, y_min-my+h))
            fig.canvas.draw_idle()  # 绘图动作实时反映在图像上
    return


def call_scroll(event):
    print(event.name)
    axtemp=event.inaxes
    print('event:',event)
    print(event.xdata,event.ydata)
    # 计算放大缩小后, xlim 和ylim
    if axtemp:
        x_min, x_max = axtemp.get_xlim()
        y_min, y_max = axtemp.get_ylim()
        w = x_max - x_min
        h = y_max - y_min
        curx=event.xdata
        cury=event.ydata
        curXposition=(curx - x_min) / w
        curYposition=(cury - y_min) / h
        if event.button == 'down':
            print('befor:',w,h)
            w = w*1.1
            h = h*1.1
            print('down',w,h)
        elif event.button == 'up':
            print('befor:',w,h)
            w = w/1.1
            h = h/1.1
            print('up',w,h)
        print(curXposition,curYposition)
        newx=curx - w*curXposition
        newy=cury - h*curYposition
        axtemp.set(xlim=(newx, newx+w))
        axtemp.set(ylim=(newy, newy+h))
        fig.canvas.draw_idle()  # 绘图动作实时反映在图像上
fig.canvas.mpl_connect('scroll_event', call_scroll)
fig.canvas.mpl_connect('button_press_event', call_move)
fig.canvas.mpl_connect('button_release_event', call_move)
# fig.canvas.mpl_connect('draw_event', call_move)
fig.canvas.mpl_connect('motion_notify_event', call_move)

# 我们可以最后来设置 x y 轴的初始大小范围
ax.set_xlim(0,10)
ax.set_ylim(0,10)

plt.show()


注意:上面demo监听的是 鼠标左键拖动, event.button==1  这个会导致和原版的工具栏 放大镜 工具冲突,所以也可以 把 event.button == 3 用鼠标右键来判断   (1 是左键,2是中间滚轮按下去键,3是右键。)

### Python 绘图示例 #### 使用 Matplotlib 进行简单正弦曲线绘制 通过 `matplotlib` 库可以轻松创建基本图表,如下所示: ```python import matplotlib.pyplot as plt import numpy as np # 创建数据 x = np.arange(0, 10, 0.1) y = np.sin(x) # 绘制线图 plt.plot(x, y) plt.xlabel('x') plt.ylabel('y') plt.title('Sin(x) Curve') plt.show() ``` 此段代码展示了如何利用 `numpy` 和 `matplotlib` 来生成一个简单的正弦波形图[^1]。 #### 利用 Seaborn 展现带分类色彩的散点图 Seaborn 是基于 Matplotlib 的高级接口库,特别适合于统计可视化。下面的例子说明了怎样使用它来显示带有不同类别颜色标记的数据集分布情况: ```python import matplotlib.pyplot as plt import seaborn as sns sns.set(rc={"axes.facecolor": "#FFF9ED", "figure.facecolor": "#FFF9ED"}) # 设置背景样式 pl = sns.scatterplot( data=data, x="Spent", y="Income", hue="clusters" ) plt.legend() # 添加图例 plt.show() ``` 这段脚本能够帮助理解多维数据分析中的群组特性,并以直观的方式呈现出来[^2]。 #### Plotly 动态交互式图表实例 Plotly 提供了一个强大的平台用于构建互动性强且美观的网页版图形。这里给出一段基础代码用来制作可缩放、拖拽式的折线图: ```python import plotly.graph_objects as go import numpy as np x = np.linspace(0, 10, 500) y = np.cos(x ** 2) fig = go.Figure(data=go.Scatter(x=x, y=y)) fig.update_layout(title='Interactive Cosine Wave', xaxis_title='X Axis Title', yaxis_title='Y Axis Title') fig.show() ``` 上述例子中,`plotly.graph_objects` 被用来定义图表对象及其属性;而 `update_layout()` 方法则允许进一步定制布局参数,最终调用 `.show()` 渲染出可视化的结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值