美文网首页
Matplotlib手绘曲线

Matplotlib手绘曲线

作者: 鱼子酱126 | 来源:发表于2021-03-25 22:28 被阅读0次

    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()
    
    
    
    
    
    
    
    
    image-20210325221531635.png

    手绘图数据

    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

    相关文章

      网友评论

          本文标题:Matplotlib手绘曲线

          本文链接:https://www.haomeiwen.com/subject/rlhdhltx.html