Matplotlib手绘曲线

Matplotlib手绘曲线

代码:

from matplotlib import pyplot as plt
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号




class LineDrawer(object):
    def __init__(self, line, axis, figure): # 将line(Line2D(matplotlib.artist.Artist)作为该类的一个属性,该类只做好数据处理与传递工作

        self.line = line
        self.axis = axis
        self.figure = figure
        
        # 用于拖拽坐标(AxesSubplot(SubplotBase, matplotlib.axes._axes.Axes))
        self.press = None
        self.cur_xlim = None
        self.cur_ylim = None
        self.x0 = None
        self.y0 = None
        self.x1 = None
        self.y1 = None
        self.xpress = None
        self.ypress = None

        # 用于将坐标点的存储
        self.lines_x_list = [] # 各分段的总数据
        self.lines_y_list = [] # 各分段的总数据

        # 撤回的回收线段
        self.undo_lines_x_list = []
        self.undo_lines_y_list = []
        
        #self.xs = list(line.get_xdata()) # xs属于自定义变量名
        #self.ys = list(line.get_ydata())
        self.cid_press = self.line.figure.canvas.mpl_connect('button_press_event', self.onPress) # 按下鼠标三键
        self.cid_release = self.line.figure.canvas.mpl_connect('button_release_event', self.onRelease) # 释放鼠标三键
        #self.cid_release = self.line.figure.canvas.mpl_connect('scroll_event', self.zoom_factory) # 滚轮



    def Get_lines_xy_show_From_lines_xy_list(self):
            #print(len(self.lines_x_list), len(self.lines_y_list))
            self.lines_x_show = [] # 取出已经画好的n段曲线
            self.lines_y_show = [] # 取出已经画好的n段曲线
            for l in self.lines_x_list:
                for x in l:
                    self.lines_x_show.append(x)
            for l in self.lines_y_list:
                for y in l:
                    self.lines_y_show.append(y)



    def onPress(self, event):
        if event.button == 3: # 鼠标右键 手绘图
            self.cid_motion = self.figure.canvas.mpl_connect("motion_notify_event", self.mouse_move)

            self.xdata_this_move = []
            self.ydata_this_move = []
            self.Get_lines_xy_show_From_lines_xy_list()


        elif event.button == 2: # 鼠标中键
            if not event.dblclick: #单击鼠标中键 撤回(撤销最后一段)
                try:
                    #print(len(self.lines_x_list), len(self.lines_y_list))
                    self.undo_lines_x_list.append(self.lines_x_list.pop(-1)) # 回收
                    self.undo_lines_y_list.append(self.lines_y_list.pop(-1)) # 回收
                except IndexError:
                    return
            else:#双击鼠标中键 取消撤回
                '''
                try:
                    #print(len(self.lines_x_list), len(self.lines_y_list))
                    self.lines_x_list.append(self.undo_lines_x_list.pop(-1)) # 取消撤回
                    self.lines_y_list.append(self.undo_lines_y_list.pop(-1)) # 取消撤回
                    
                except IndexError:
                    return
                '''
                pass
            self.Get_lines_xy_show_From_lines_xy_list()
            #print(len(self.lines_x_show), len(self.lines_y_show))
            self.line.set_data(self.lines_x_show, self.lines_y_show) # 连接各段,全部画出来
            #self.line.figure.canvas.get_renderer(cleared=True)
            self.line.figure.canvas.draw_idle()



    def mouse_move(self, event):

        self.xdata_this_move.append(event.xdata)
        self.ydata_this_move.append(event.ydata)

        self.lines_x_show.append(event.xdata)
        self.lines_y_show.append(event.ydata)

        self.line.set_data(self.lines_x_show, self.lines_y_show) # 连接各段,全部画出来
        self.line.figure.canvas.draw_idle() # 数据重画


    def onRelease(self, event):
        if event.button == 3: # 鼠标右键 手绘图
            self.cid_release = self.figure.canvas.mpl_disconnect(self.cid_motion)

            self.lines_x_list.append(self.xdata_this_move) # 释放后添加本次运动的x点
            self.lines_y_list.append(self.ydata_this_move) # 释放后添加本次运动的y点

            #print(self.xdata_this_move, self.ydata_this_move, '\n==================\n\n')


    # 缩放
    def zoom_factory(self, base_scale=1.1):
        # ax (AxesSubplot(SubplotBase, matplotlib.axes._axes.Axes))
        def zoom(event):
            cur_xlim = self.axis.get_xlim()
            cur_ylim = self.axis.get_ylim()

            xdata = event.xdata # get event x location
            ydata = event.ydata # get event y location

            if event.button == 'down':
                # deal with zoom in
                scale_factor = 1 / base_scale
            elif event.button == 'up':
                # deal with zoom out
                scale_factor = base_scale
            else:
                # deal with something that should never happen
                scale_factor = 1
                #print(event.button)

            new_width = (cur_xlim[1] - cur_xlim[0]) * scale_factor
            new_height = (cur_ylim[1] - cur_ylim[0]) * scale_factor

            relx = (cur_xlim[1] - xdata)/(cur_xlim[1] - cur_xlim[0])
            rely = (cur_ylim[1] - ydata)/(cur_ylim[1] - cur_ylim[0])

            self.axis.set_xlim([xdata - new_width * (1-relx), xdata + new_width * (relx)])
            self.axis.set_ylim([ydata - new_height * (1-rely), ydata + new_height * (rely)])
            self.axis.figure.canvas.draw() # 数据重画

        #fig = self.axis.get_figure() # get the figure of interest
        self.figure.canvas.mpl_connect('scroll_event', zoom)

        return zoom

    # 左键拖动
    def pan_factory(self):
        def onPress(event):
            if event.button == 1:
                if event.inaxes != self.axis: return
                self.cur_xlim = self.axis.get_xlim()
                self.cur_ylim = self.axis.get_ylim()
                self.press = self.x0, self.y0, event.xdata, event.ydata
                self.x0, self.y0, self.xpress, self.ypress = self.press

        def onRelease(event):
            self.press = None
            self.axis.figure.canvas.draw() # 数据重画

        def onMotion(event):
            if self.press is None: return
            if event.inaxes != self.axis: return
            dx = event.xdata - self.xpress
            dy = event.ydata - self.ypress
            self.cur_xlim -= dx
            self.cur_ylim -= dy
            self.axis.set_xlim(self.cur_xlim)
            self.axis.set_ylim(self.cur_ylim)

            self.axis.figure.canvas.draw() # 数据重画

        #fig = self.axis.get_figure() # get the figure of interest

        # attach the call back
        self.figure.canvas.mpl_connect('button_press_event',onPress)
        self.figure.canvas.mpl_connect('button_release_event',onRelease)
        self.figure.canvas.mpl_connect('motion_notify_event',onMotion)

        #return the function
        return onMotion




def main():
    l = [500, 657, 814, 971, 1128, 1285, 1442, 1599, 1756, 1913, 2070, 1913, 1756, 1599, 1442, 1285, 1128, 971, 814, 657, 500, 1518, 575, 1725, 500]
    X = []
    Y = []
    n = 0
    for i in l:
        for j in range(120):
            n += 1
            X.append(n)
            Y.append(i)


    fig = plt.figure()
    ax = fig.add_subplot(111) # class AxesSubplot(SubplotBase, matplotlib.axes._axes.Axes)
    ax.set_title('Matplotlib手绘曲线')
    line_fix, = ax.plot(X, Y, lw='0.5')
    line_draw_by_hand, = ax.plot([], [], lw=1)
    linebuilder = LineDrawer(line=line_draw_by_hand, axis=ax, figure=fig)
    figZoom = linebuilder.zoom_factory(base_scale = 1.1)
    figPan = linebuilder.pan_factory()
    plt.show()
    # 关闭图像后, 再执行以下代码


    X_line_draw = []
    Y_line_draw = []
    for l in linebuilder.lines_x_list:
        for i in l:
            X_line_draw.append(i)
    for l in linebuilder.lines_y_list:
        for i in l:
            Y_line_draw.append(i)

    out = open('手绘数据.txt', 'w', encoding='utf8')
    for i in range(len(X_line_draw)):
        x = X_line_draw[i]
        y = Y_line_draw[i]
        out.write(f'{x}\t{y}\n')
    out.close()




if __name__ == '__main__':
    main()







在这里插入图片描述

手绘图数据

25.638961693548367	546.1584093872231
36.72397513440853	557.8551871856957
50.580241935483855	563.7035760849321
50.580241935483855	560.7793816353139
50.580241935483855	554.9309927360775
64.43650873655906	563.7035760849321
147.57410954301065	657.2777984727138
216.85544354838703	762.5487986589683
214.084190188172	762.5487986589683
208.5416834677419	756.7004097597319
214.084190188172	791.79074315515
244.56797715053756	891.2133544421681
261.1954973118279	917.5311044887317
261.1954973118279	891.2133544421681
297.2217909946236	867.8197988452226
336.01933803763427	929.2278822872045
358.1893649193547	1025.7262991246043
363.7318716397848	1034.498882473459
380.35939180107505	1008.1811324268953
408.0719254032257	1014.0295213261317
424.69944556451594	1028.6504935742225
546.6345934139782	1163.1634382566588
627.0009408602149	1300.6005773887132
657.4847278225806	1326.9183274352768
660.2559811827956	1312.297355187186
665.7984879032257	1312.297355187186
693.5110215053761	1411.719966474204
723.9948084677418	1502.3699944123675
746.1648353494621	1458.5070776680948
779.4198756720428	1402.9473831253495
796.0473958333331	1423.4167442726766
832.0736895161289	1522.8393555596947
895.812516801075	1654.428105792513
912.4400369623653	1669.0490780406037
915.2112903225803	1651.5039113428948
948.4663306451611	1677.8216613894583
1017.7476646505373	1753.850717079531
1120.2840389784942	1873.7426895138763
1167.3953461021501	1914.6814118085308
1178.4803595430103	1879.5910784131127
1192.3366263440857	1870.818495064258
1220.0491599462362	1917.605606258149
1231.1341733870963	1929.3023840566216
1239.4479334677417	1926.3781896070034
1727.1885248655913	1505.2941888619857
1724.417271505376	1484.8248277146586
1724.417271505376	1478.9764388154222
1735.5022849462362	1473.1280499161858
1763.2148185483866	1493.597411063513
1782.613592069892	1443.886105420004
1824.182392473118	1297.676382939095
1838.0386592741934	1318.1457440864224
1879.6074596774188	1373.7054386291677
1907.3199932795696	1332.7667163345131
1943.3462869623654	1291.8279940398586
1932.2612735215048	1280.131216241386
2084.6802083333328	970.1666045818589
2106.8502352150535	920.4552989383499
2112.3927419354836	917.5311044887317
2156.7327956989243	926.3036878375863
2167.8178091397845	926.3036878375863
2228.785383064516	911.6827155894954
2298.066717069892	891.2133544421681
2300.837970430107	894.1375488917863

主页:https://www.zhihu.com/people/caviar126

猜你喜欢

转载自blog.csdn.net/caviar126/article/details/115220510
今日推荐