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


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

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

    效果:


    上代码:

    1. import matplotlib.pyplot as plt
    2. import matplotlib as mpl
    3. from matplotlib.text import Text, Annotation
    4. from matplotlib.patches import Polygon, Rectangle, Circle, Arrow, ConnectionPatch,Ellipse,FancyBboxPatch
    5. from matplotlib.widgets import Button, Slider, Widget
    6. # https://www.python100.com/html/85915.html
    7. # patches 是matplotlib里面的一个库,里面有基本图形绘制, Polygon:多边形 Rectangle:矩形 Circle:圆 Arrow:箭头 ConnecctionPatch:链接线 Ellipse:椭圆
    8. fig = plt.figure()
    9. ax = fig.add_subplot(111)
    10. rect = Rectangle((0.1,0.1),1,1,color='yellow')
    11. ax.add_patch(rect)
    12. rect2 = Circle((1.5,1.5),0.2,color='red')
    13. ax.add_patch(rect2)
    14. arrow = ConnectionPatch((1,3),(1.8,1.8), "data", "data", clip_on=True,
    15. arrowstyle="-|>", shrinkA=5, shrinkB=5, mutation_scale=20, fc="w")
    16. arrow.set_annotation_clip(False)
    17. ax.add_patch(arrow)
    18. fancybox = FancyBboxPatch((2,2),width=1,height=1, boxstyle=mpl.patches.BoxStyle("Round", pad=0.2),color='green')
    19. ax.add_patch(fancybox)
    20. ax.text(2, 0.2, 'Hello World')
    21. startx=0
    22. starty=0
    23. mPress=False
    24. def call_move(event):
    25. # print(event.name)
    26. global mPress
    27. global startx
    28. global starty
    29. # print(mPress)
    30. if event.name=='button_press_event':
    31. axtemp=event.inaxes
    32. if axtemp and event.button==1:
    33. print(event)
    34. mPress=True
    35. startx=event.xdata
    36. starty=event.ydata
    37. elif event.name=='button_release_event':
    38. axtemp=event.inaxes
    39. if axtemp and event.button==1:
    40. mPress=False
    41. elif event.name=='motion_notify_event':
    42. axtemp=event.inaxes
    43. if axtemp and event.button==1 and mPress:
    44. x_min, x_max = axtemp.get_xlim()
    45. y_min, y_max = axtemp.get_ylim()
    46. w=x_max-x_min
    47. h=y_max-y_min
    48. # print(event)
    49. # 移动
    50. mx=event.xdata-startx
    51. my=event.ydata-starty
    52. # 注意这里, -mx, 因为下一次 motion事件的坐标,已经是在本次做了移动之后的坐标系了,所以要体现出来
    53. # startx=event.xdata-mx startx=event.xdata-(event.xdata-startx)=startx, 没必要再赋值了
    54. # starty=event.ydata-my
    55. # print(mx,my,x_min,y_min,w,h)
    56. axtemp.set(xlim=(x_min-mx, x_min-mx+w))
    57. axtemp.set(ylim=(y_min-my, y_min-my+h))
    58. fig.canvas.draw_idle() # 绘图动作实时反映在图像上
    59. return
    60. def call_scroll(event):
    61. print(event.name)
    62. axtemp=event.inaxes
    63. print('event:',event)
    64. print(event.xdata,event.ydata)
    65. # 计算放大缩小后, xlim 和ylim
    66. if axtemp:
    67. x_min, x_max = axtemp.get_xlim()
    68. y_min, y_max = axtemp.get_ylim()
    69. w = x_max - x_min
    70. h = y_max - y_min
    71. curx=event.xdata
    72. cury=event.ydata
    73. curXposition=(curx - x_min) / w
    74. curYposition=(cury - y_min) / h
    75. if event.button == 'down':
    76. print('befor:',w,h)
    77. w = w*1.1
    78. h = h*1.1
    79. print('down',w,h)
    80. elif event.button == 'up':
    81. print('befor:',w,h)
    82. w = w/1.1
    83. h = h/1.1
    84. print('up',w,h)
    85. print(curXposition,curYposition)
    86. newx=curx - w*curXposition
    87. newy=cury - h*curYposition
    88. axtemp.set(xlim=(newx, newx+w))
    89. axtemp.set(ylim=(newy, newy+h))
    90. fig.canvas.draw_idle() # 绘图动作实时反映在图像上
    91. fig.canvas.mpl_connect('scroll_event', call_scroll)
    92. fig.canvas.mpl_connect('button_press_event', call_move)
    93. fig.canvas.mpl_connect('button_release_event', call_move)
    94. # fig.canvas.mpl_connect('draw_event', call_move)
    95. fig.canvas.mpl_connect('motion_notify_event', call_move)
    96. # 我们可以最后来设置 x y 轴的初始大小范围
    97. ax.set_xlim(0,10)
    98. ax.set_ylim(0,10)
    99. plt.show()

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

  • 相关阅读:
    职场人,该看重机遇,还是该注重自己的能力?
    android 闪屏图适配尺寸
    AI绘画工具介绍
    xauth: file /home/oracle/.Xauthority does not exist解决方案
    vue3中路由hash与History的设置
    CentOS 7.9检测硬盘坏区、实物定位(三)
    企业转型升级之道:数字化转型,思想先行
    Java基于SpringBoot+Vue的 4S店车辆管理系统
    Vue中的样式绑定
    艾美捷细胞失巢凋亡检测试剂盒测定原理
  • 原文地址:https://blog.csdn.net/u012459903/article/details/134000006