Module hydroinform.hyplot

Source code
# -*- coding: utf-8 -*-
from hydroinform.hymod import *
import matplotlib.pyplot as plt


class PlanPlot():
    def __init__(self, reaches = [], fig=None, position=111, show=False, xssPlot=None, profilePlot=None, dem=None, showWaterLevel=False, show_normal_depths=False):
        self.dem = dem #digital elevation model as background (xx, yy, dem)
        self.reaches = reaches
        self.fig = fig
        self.show = show
        self.position = position
        self.xssPlot = xssPlot
        self.profilePlot = profilePlot
        if self.fig is None:
            self.fig = plt.figure()
        self.ax = self.fig.add_subplot(self.position)
        self.ax.set_aspect('equal', 'datalim')
        self.pathcolls = []
        self.firstTimeOnReachPickEvent = True
        self.yellowLine = None # The yellow marker that indicates which crosssection that is selected.
        self.pickedReachIndex = None
        self.pickedXsIndex = None
        self.fig.canvas.mpl_connect('pick_event', self.on_reachpick)
        self.fig.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.showWaterLevel = showWaterLevel
        self.show_perimenter_points = False
        self.show_normal_depths = show_normal_depths
        self.plot()

    def on_reachpick(self, event):
        if self.xssPlot is None:
            self.xssPlot = XssPlot()
            self.xssPlot.showWaterLevel = self.showWaterLevel
            print('created new xss plot')

        if self.profilePlot is None:
            self.profilePlot = ProfilePlot()
            self.profilePlot.showWaterLevel = self.showWaterLevel
            self.profilePlot.show_normal_depths = self.show_normal_depths
            print('created new profile plot')

        self.pickedReachIndex = self.pathcolls.index(event.artist)
        self.pickedXsIndex = event.ind[0]
        self.ax.set_title(self.reaches[self.pickedReachIndex].name)
        pickedXs = self.reaches[self.pickedReachIndex].xss[self.pickedXsIndex]
        self.profilePlot.update(self.reaches[self.pickedReachIndex], pickedXs)
        self.xssPlot.update(pickedXs)
        if self.firstTimeOnReachPickEvent:
            self.firstTimeOnReachPickEvent = False
            self.yellowLine, = self.ax.plot([pickedXs.x], [pickedXs.y], marker='o', color='y')
            plt.show()
        else:
            self.yellowLine.set_data([pickedXs.x], [pickedXs.y])
            self.fig.canvas.draw()

    def on_key_press(self, event):
        print('press', event.key)
        if (event.key == 'right' or event.key == 'left') and self.firstTimeOnReachPickEvent == False:
            if event.key == 'right':
                if self.pickedXsIndex == len(self.reaches[self.pickedReachIndex].xss) - 1:
                    self.pickedXsIndex = 0
                else:
                    self.pickedXsIndex += 1
            elif event.key == 'left':
                if self.pickedXsIndex == 0:
                    self.pickedXsIndex = len(self.reaches[self.pickedReachIndex].xss) - 1
                else:
                    self.pickedXsIndex -= 1

            pickedXs = self.reaches[self.pickedReachIndex].xss[self.pickedXsIndex]
            self.xssPlot.update(pickedXs)
            self.profilePlot.update(self.reaches[self.pickedReachIndex], pickedXs)
            self.yellowLine.set_data([pickedXs.x], [pickedXs.y])
            self.fig.canvas.draw()


    def plot(self):
        for reach in self.reaches:
            if self.dem:
                contour_levels = np.arange(-2, 2, 0.1)
                self.ax.contourf(self.dem[0], self.dem[1], self.dem[2], contour_levels, cmap='terrain', zorder=0)
            self.ax.plot([p.x for p in reach.riverPoints], [p.y for p in reach.riverPoints], color='b', zorder=1)
            pathcoll = self.ax.scatter([p.x for p in reach.xss], [p.y for p in reach.xss], marker='o', color='b', picker=5)
            self.ax.scatter([xs.x for xs in reach.xss if xs.is_closed], [xs.y for xs in reach.xss if xs.is_closed], marker='o', color='green', zorder=2) #Marking xs which are closed
            self.ax.scatter([xs.x for xs in reach.xss if xs.is_weir], [xs.y for xs in reach.xss if xs.is_weir], marker='o', color='red', zorder=3)  # Marking xs which are weirs
            self.pathcolls.append(pathcoll)
            if self.show_perimenter_points is True:
                for reach in self.reaches:
                    for xs in reach.xss:
                        self.ax.plot([pp.x for pp in xs.pps], [pp.y for pp in xs.pps], marker='x', color='green', zorder=0)

        if self.show:
            plt.show()


class XssPlot():
    def __init__(self, xss = [], fig=None, position=111, show=False, showWaterLevel=False):
        self.xss = xss
        self.position = position
        self.show = show
        self.showWaterLevel = showWaterLevel
        self.ax = None
        self.fig = fig
        if self.fig == None:
            self.fig = plt.figure()
        self.ax = self.fig.add_subplot(self.position)
        self.fig.canvas.mpl_connect('key_press_event', self.press)
        self.plot()
        print('XssPlot __init__(...) completed.')

    def press(self, event):
        if event.key == 'escape':
            lastXs = self.xss[-1]
            self.xss = [lastXs]
            self.ax.clear()
            self.plot()

    def plot(self):
        if len(self.xss) > 0:
            for n in range(len(self.xss) - 1):
                xp, zp = [p.dx for p in self.xss[n].pps], [p.dz + self.xss[n].z for p in self.xss[n].pps]
                self.ax.plot(xp, zp, color='gray', zorder=0)
                self.ax.scatter(xp, zp, color='gray', zorder=0)

            self.ax.plot([p.dx for p in self.xss[-1].pps], [p.dz + self.xss[-1].z for p in self.xss[-1].pps], color='k', zorder=1)
            self.ax.scatter([p.dx for p in self.xss[-1].pps], [p.dz + self.xss[-1].z for p in self.xss[-1].pps], color='k', zorder=1)

            leftbank_points = [p for p in self.xss[-1].pps if p.marker == 'left bank']
            self.ax.scatter([p.dx for p in leftbank_points], [p.dz + self.xss[-1].z for p in leftbank_points], color='r', marker='o', zorder=2)
            rightbank_points = [p for p in self.xss[-1].pps if p.marker == 'right bank']
            self.ax.scatter([p.dx for p in rightbank_points], [p.dz + self.xss[-1].z for p in rightbank_points], color='b', marker='o',zorder=2)
            center_points = [p for p in self.xss[-1].pps if p.marker == 'center']
            self.ax.scatter([p.dx for p in center_points], [p.dz + self.xss[-1].z for p in center_points], color='y', marker='o',zorder=2)

            if self.showWaterLevel:
                wps = self.xss[-1].get_wetted_polygon(self.xss[-1].depth)
                self.ax.fill([p.dx for p in wps], [p.dz + self.xss[-1].z for p in wps], zorder=0)

            if self.xss[-1].is_closed:
                is_closed_str = 'closed xs'
            else:
                is_closed_str = 'open xs'
            self.ax.set_title('Chainage: ' + str(self.xss[-1].chainage) + ' ' + is_closed_str)
            self.fig.canvas.draw()

            if self.show:
                plt.show()

    def update(self, xs):
        self.ax.clear()
        while xs in self.xss:
            self.xss.remove(xs)

        self.xss.append(xs)

        print('updated XssPlot')
        self.plot()


class ProfilePlot():
    def __init__(self, reach=None, fig=None, position=111, showBanks=True, showWaterLevel = False, show=True, show_normal_depths=False):
        self.reach = reach
        self.position = position
        self.show = show
        self.showBanks = showBanks
        self.showWaterLevel = showWaterLevel
        self.show_normal_depths = show_normal_depths
        self.ax = None
        self.fig = fig
        self.yellowLine = None  # The yellow marker that indicates which crosssection that is selected.
        if self.fig is None:
            self.fig = plt.figure()
        self.ax = self.fig.add_subplot(self.position)
        self.plot()

    def plot(self):
        if self.reach != None:
            chainages = [xs.chainage for xs in self.reach.xss]
            zmins = [xs.z for xs in self.reach.xss]
            self.ax.plot(chainages, zmins, color='k', marker='o', zorder=1)
            self.ax.scatter([xs.chainage for xs in self.reach.xss if xs.is_closed], [xs.z for xs in self.reach.xss if xs.is_closed], marker='o', color='green', zorder=2)  # Marking xs which are closed
            self.ax.scatter([xs.chainage for xs in self.reach.xss if xs.is_weir], [xs.z for xs in self.reach.xss if xs.is_weir], marker='o', color='red', zorder=3)  # Marking xs which are weirs

            if self.showBanks:
                self.ax.plot(chainages, [xs.pps[0].dz + xs.z for xs in self.reach.xss], '--', color='k')
                self.ax.plot(chainages, [xs.pps[-1].dz + xs.z for xs in self.reach.xss], '--', color='k')

            if self.showWaterLevel:
                if len(self.reach.calculated_water_levels) == 0:
                    self.ax.plot(chainages, [xs.depth + xs.z for xs in self.reach.xss], color='b', zorder=10, label='calculated water level')
                else:
                    self.ax.plot([wl[0] for wl in self.reach.calculated_water_levels],[wl[1] for wl in self.reach.calculated_water_levels], color='b', zorder=10)

            # for observation in self.reach.observations:
            #     self.ax.scatter([a[0] for a in observation.chainage_waterlevels], [a[1] for a in observation.chainage_waterlevels], marker='o', color='red', label=observation.name, zorder=20)

            self.ax.scatter([a[0] for a in self.reach.observations], [a[1] for a in self.reach.observations], marker='o', color='red', label='Observed', zorder=20)

            if self.show_normal_depths:
                chs = []
                normal_depths = []
                for n in range(len(self.reach.xss) - 1):
                    slope = (self.reach.xss[n + 1].z - self.reach.xss[n].z) / (self.reach.xss[n + 1].chainage - self.reach.xss[n].chainage)
                    if slope > 0.:
                        chs.append((self.reach.xss[n].chainage + self.reach.xss[n + 1].chainage) / 2.)
                        z_mean = (self.reach.xss[n].z + self.reach.xss[n + 1].z) / 2.
                        normal_depths.append(z_mean + self.reach.xss[n].get_normal_depth(slope))
                self.ax.scatter(chs, normal_depths, marker='o', color='green', label='Normal depth')

            # if showLabels:
            #     for i, j in zip(chainages, zmins):
            #         ax.annotate('%s)' % j, xy=(i, j), xytext=(30, 0), textcoords='offset points')
            #         ax.annotate('(%s,' % i, xy=(i, j))
            #
            # if showGrid:
            #     ax.grid()
            self.ax.legend()

            self.ax.set_title(self.reach.name)
            self.fig.canvas.draw()
            if self.show is True:
                plt.show()

    def update(self, reach, xs):
        # if reach != self.reach: TODO: linjerne er udkommenteret da det ellers ikke virker, men figuren flikker...
            self.ax.clear()
            self.reach = reach
            self.yellowLine, = self.ax.plot([xs.chainage],[xs.z], marker='o', color='y', linestyle=' ', zorder=3)
            self.plot()

        # else:
        #     self.yellowLine.set_data([xs.chainage], [xs.z])
        #     self.fig.canvas.draw()



def plot(obj, show=True, showWaterLevel=False, use_seperate_windows=False, show_normal_depths=False, dem=None):  # Plotting whatever is passed as obj
    """
    General plotting of hymod related data. Depending on the object type passed different plot types is shown. However,
    normally you will pass an object of type hymod.Reach_network. This will generate a plot with three subplots. A plan
    plot, a cross section plot and a profile plot. When clicking on a cross section in the plan plot, the cross section
    plot and the profile plot will show the associated cross section and reach, respectively. The cross section plot
    includes history, which means that previously selected cross sections is shown in a grey color. Pressing the escape
    key will clear the history. You can use right arrow and left arrow keys to navigate to the next cross section in a
    reach. In the plan plot and the profile black dots are open cross sections, green dots are closed cross sections and
    red dots are weirs. River banks are shown as dashed black lines. Observed water levels is shown in the profile plot
    if the property hymod.Reach.Observations is populated (see further documentation for this in the Reach code)
    :param obj: object instances of types allowed: hymod.Xs, [hymod.Xs], hymod.Reach, [hymod.Reach], hymod.Reach_network
    :param show: For most cases leave this as the default True value. If false the plot is not shown. (used in special cases)
    :param showWaterLevel: When True, calculated water levels are shown in profile plots and cross sections plots
    :param use_seperate_windows: When False: All plots are shown in the same figure. When True three seperate windows appear
    :param show_normal_depths: When True, normal depth are shown as scatter points in the profile plot
    """
    if isinstance(obj, Xs):  # a single crosssection
        XssPlot([obj], show=show, showWaterLevel=showWaterLevel).plot()

    elif isinstance(obj, list) and isinstance(obj[0], Xs):  # a list of crosssections
        XssPlot(obj, show=show, showWaterLevel=showWaterLevel).plot()

    elif isinstance(obj, Reach): # a single reach
        PlanPlot([obj], show=show, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths).plot()

    elif isinstance(obj, list) and isinstance(obj[0], Reach): # a list of reaches
        PlanPlot(obj, show=show, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths).plot()

    elif isinstance(obj, Reach_network):
        if use_seperate_windows:
            xsPlot = XssPlot(fig=plt.figure(), position=111, showWaterLevel=showWaterLevel)
            profilePlot = ProfilePlot(fig=plt.figure(), position=111, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths)
            planPlot = PlanPlot(reaches=obj.reaches, fig=plt.figure(), position=111, xssPlot=xsPlot, profilePlot=profilePlot, dem=dem)

        else:
            fig = plt.figure()
            xsPlot = XssPlot(fig=fig, position=222, showWaterLevel=showWaterLevel)
            profilePlot = ProfilePlot(fig=fig, position=212, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths)
            planPlot = PlanPlot(reaches=obj.reaches, fig=fig, position=221, xssPlot=xsPlot, profilePlot=profilePlot, dem=dem)

        if show:
            plt.show()
    else:
        raise TypeError('non recognized type passed to plot function')

#TODO: dette er et midlertidig hack. Jeg tror at de skal laves med et object og ikke med en static method, saa man kan saette flere parametre (e.g. contour levels etc.)
# def plot_reach_network(reach_network, show=True, showWaterLevel=False, dem=None):
#     fig = plt.figure()
#     xsPlot = XssPlot(fig=fig, position=222, showWaterLevel=showWaterLevel)
#     profilePlot = ProfilePlot(fig=fig, position=212, showWaterLevel=showWaterLevel)
#     planPlot = PlanPlot(reaches=reach_network.reaches, fig=fig, position=221, xssPlot=xsPlot, profilePlot=profilePlot, dem=dem)
#     if show:
#         plt.show()

Functions

def plot(obj, show=True, showWaterLevel=False, use_seperate_windows=False, show_normal_depths=False, dem=None)

General plotting of hymod related data. Depending on the object type passed different plot types is shown. However, normally you will pass an object of type hymod.Reach_network. This will generate a plot with three subplots. A plan plot, a cross section plot and a profile plot. When clicking on a cross section in the plan plot, the cross section plot and the profile plot will show the associated cross section and reach, respectively. The cross section plot includes history, which means that previously selected cross sections is shown in a grey color. Pressing the escape key will clear the history. You can use right arrow and left arrow keys to navigate to the next cross section in a reach. In the plan plot and the profile black dots are open cross sections, green dots are closed cross sections and red dots are weirs. River banks are shown as dashed black lines. Observed water levels is shown in the profile plot if the property hymod.Reach.Observations is populated (see further documentation for this in the Reach code) :param obj: object instances of types allowed: hymod.Xs, [hymod.Xs], hymod.Reach, [hymod.Reach], hymod.Reach_network :param show: For most cases leave this as the default True value. If false the plot is not shown. (used in special cases) :param showWaterLevel: When True, calculated water levels are shown in profile plots and cross sections plots :param use_seperate_windows: When False: All plots are shown in the same figure. When True three seperate windows appear :param show_normal_depths: When True, normal depth are shown as scatter points in the profile plot

Source code
def plot(obj, show=True, showWaterLevel=False, use_seperate_windows=False, show_normal_depths=False, dem=None):  # Plotting whatever is passed as obj
    """
    General plotting of hymod related data. Depending on the object type passed different plot types is shown. However,
    normally you will pass an object of type hymod.Reach_network. This will generate a plot with three subplots. A plan
    plot, a cross section plot and a profile plot. When clicking on a cross section in the plan plot, the cross section
    plot and the profile plot will show the associated cross section and reach, respectively. The cross section plot
    includes history, which means that previously selected cross sections is shown in a grey color. Pressing the escape
    key will clear the history. You can use right arrow and left arrow keys to navigate to the next cross section in a
    reach. In the plan plot and the profile black dots are open cross sections, green dots are closed cross sections and
    red dots are weirs. River banks are shown as dashed black lines. Observed water levels is shown in the profile plot
    if the property hymod.Reach.Observations is populated (see further documentation for this in the Reach code)
    :param obj: object instances of types allowed: hymod.Xs, [hymod.Xs], hymod.Reach, [hymod.Reach], hymod.Reach_network
    :param show: For most cases leave this as the default True value. If false the plot is not shown. (used in special cases)
    :param showWaterLevel: When True, calculated water levels are shown in profile plots and cross sections plots
    :param use_seperate_windows: When False: All plots are shown in the same figure. When True three seperate windows appear
    :param show_normal_depths: When True, normal depth are shown as scatter points in the profile plot
    """
    if isinstance(obj, Xs):  # a single crosssection
        XssPlot([obj], show=show, showWaterLevel=showWaterLevel).plot()

    elif isinstance(obj, list) and isinstance(obj[0], Xs):  # a list of crosssections
        XssPlot(obj, show=show, showWaterLevel=showWaterLevel).plot()

    elif isinstance(obj, Reach): # a single reach
        PlanPlot([obj], show=show, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths).plot()

    elif isinstance(obj, list) and isinstance(obj[0], Reach): # a list of reaches
        PlanPlot(obj, show=show, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths).plot()

    elif isinstance(obj, Reach_network):
        if use_seperate_windows:
            xsPlot = XssPlot(fig=plt.figure(), position=111, showWaterLevel=showWaterLevel)
            profilePlot = ProfilePlot(fig=plt.figure(), position=111, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths)
            planPlot = PlanPlot(reaches=obj.reaches, fig=plt.figure(), position=111, xssPlot=xsPlot, profilePlot=profilePlot, dem=dem)

        else:
            fig = plt.figure()
            xsPlot = XssPlot(fig=fig, position=222, showWaterLevel=showWaterLevel)
            profilePlot = ProfilePlot(fig=fig, position=212, showWaterLevel=showWaterLevel, show_normal_depths=show_normal_depths)
            planPlot = PlanPlot(reaches=obj.reaches, fig=fig, position=221, xssPlot=xsPlot, profilePlot=profilePlot, dem=dem)

        if show:
            plt.show()
    else:
        raise TypeError('non recognized type passed to plot function')

Classes

class PlanPlot (reaches=[], fig=None, position=111, show=False, xssPlot=None, profilePlot=None, dem=None, showWaterLevel=False, show_normal_depths=False)
Source code
class PlanPlot():
    def __init__(self, reaches = [], fig=None, position=111, show=False, xssPlot=None, profilePlot=None, dem=None, showWaterLevel=False, show_normal_depths=False):
        self.dem = dem #digital elevation model as background (xx, yy, dem)
        self.reaches = reaches
        self.fig = fig
        self.show = show
        self.position = position
        self.xssPlot = xssPlot
        self.profilePlot = profilePlot
        if self.fig is None:
            self.fig = plt.figure()
        self.ax = self.fig.add_subplot(self.position)
        self.ax.set_aspect('equal', 'datalim')
        self.pathcolls = []
        self.firstTimeOnReachPickEvent = True
        self.yellowLine = None # The yellow marker that indicates which crosssection that is selected.
        self.pickedReachIndex = None
        self.pickedXsIndex = None
        self.fig.canvas.mpl_connect('pick_event', self.on_reachpick)
        self.fig.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.showWaterLevel = showWaterLevel
        self.show_perimenter_points = False
        self.show_normal_depths = show_normal_depths
        self.plot()

    def on_reachpick(self, event):
        if self.xssPlot is None:
            self.xssPlot = XssPlot()
            self.xssPlot.showWaterLevel = self.showWaterLevel
            print('created new xss plot')

        if self.profilePlot is None:
            self.profilePlot = ProfilePlot()
            self.profilePlot.showWaterLevel = self.showWaterLevel
            self.profilePlot.show_normal_depths = self.show_normal_depths
            print('created new profile plot')

        self.pickedReachIndex = self.pathcolls.index(event.artist)
        self.pickedXsIndex = event.ind[0]
        self.ax.set_title(self.reaches[self.pickedReachIndex].name)
        pickedXs = self.reaches[self.pickedReachIndex].xss[self.pickedXsIndex]
        self.profilePlot.update(self.reaches[self.pickedReachIndex], pickedXs)
        self.xssPlot.update(pickedXs)
        if self.firstTimeOnReachPickEvent:
            self.firstTimeOnReachPickEvent = False
            self.yellowLine, = self.ax.plot([pickedXs.x], [pickedXs.y], marker='o', color='y')
            plt.show()
        else:
            self.yellowLine.set_data([pickedXs.x], [pickedXs.y])
            self.fig.canvas.draw()

    def on_key_press(self, event):
        print('press', event.key)
        if (event.key == 'right' or event.key == 'left') and self.firstTimeOnReachPickEvent == False:
            if event.key == 'right':
                if self.pickedXsIndex == len(self.reaches[self.pickedReachIndex].xss) - 1:
                    self.pickedXsIndex = 0
                else:
                    self.pickedXsIndex += 1
            elif event.key == 'left':
                if self.pickedXsIndex == 0:
                    self.pickedXsIndex = len(self.reaches[self.pickedReachIndex].xss) - 1
                else:
                    self.pickedXsIndex -= 1

            pickedXs = self.reaches[self.pickedReachIndex].xss[self.pickedXsIndex]
            self.xssPlot.update(pickedXs)
            self.profilePlot.update(self.reaches[self.pickedReachIndex], pickedXs)
            self.yellowLine.set_data([pickedXs.x], [pickedXs.y])
            self.fig.canvas.draw()


    def plot(self):
        for reach in self.reaches:
            if self.dem:
                contour_levels = np.arange(-2, 2, 0.1)
                self.ax.contourf(self.dem[0], self.dem[1], self.dem[2], contour_levels, cmap='terrain', zorder=0)
            self.ax.plot([p.x for p in reach.riverPoints], [p.y for p in reach.riverPoints], color='b', zorder=1)
            pathcoll = self.ax.scatter([p.x for p in reach.xss], [p.y for p in reach.xss], marker='o', color='b', picker=5)
            self.ax.scatter([xs.x for xs in reach.xss if xs.is_closed], [xs.y for xs in reach.xss if xs.is_closed], marker='o', color='green', zorder=2) #Marking xs which are closed
            self.ax.scatter([xs.x for xs in reach.xss if xs.is_weir], [xs.y for xs in reach.xss if xs.is_weir], marker='o', color='red', zorder=3)  # Marking xs which are weirs
            self.pathcolls.append(pathcoll)
            if self.show_perimenter_points is True:
                for reach in self.reaches:
                    for xs in reach.xss:
                        self.ax.plot([pp.x for pp in xs.pps], [pp.y for pp in xs.pps], marker='x', color='green', zorder=0)

        if self.show:
            plt.show()

Methods

def on_key_press(self, event)
Source code
def on_key_press(self, event):
    print('press', event.key)
    if (event.key == 'right' or event.key == 'left') and self.firstTimeOnReachPickEvent == False:
        if event.key == 'right':
            if self.pickedXsIndex == len(self.reaches[self.pickedReachIndex].xss) - 1:
                self.pickedXsIndex = 0
            else:
                self.pickedXsIndex += 1
        elif event.key == 'left':
            if self.pickedXsIndex == 0:
                self.pickedXsIndex = len(self.reaches[self.pickedReachIndex].xss) - 1
            else:
                self.pickedXsIndex -= 1

        pickedXs = self.reaches[self.pickedReachIndex].xss[self.pickedXsIndex]
        self.xssPlot.update(pickedXs)
        self.profilePlot.update(self.reaches[self.pickedReachIndex], pickedXs)
        self.yellowLine.set_data([pickedXs.x], [pickedXs.y])
        self.fig.canvas.draw()
def on_reachpick(self, event)
Source code
def on_reachpick(self, event):
    if self.xssPlot is None:
        self.xssPlot = XssPlot()
        self.xssPlot.showWaterLevel = self.showWaterLevel
        print('created new xss plot')

    if self.profilePlot is None:
        self.profilePlot = ProfilePlot()
        self.profilePlot.showWaterLevel = self.showWaterLevel
        self.profilePlot.show_normal_depths = self.show_normal_depths
        print('created new profile plot')

    self.pickedReachIndex = self.pathcolls.index(event.artist)
    self.pickedXsIndex = event.ind[0]
    self.ax.set_title(self.reaches[self.pickedReachIndex].name)
    pickedXs = self.reaches[self.pickedReachIndex].xss[self.pickedXsIndex]
    self.profilePlot.update(self.reaches[self.pickedReachIndex], pickedXs)
    self.xssPlot.update(pickedXs)
    if self.firstTimeOnReachPickEvent:
        self.firstTimeOnReachPickEvent = False
        self.yellowLine, = self.ax.plot([pickedXs.x], [pickedXs.y], marker='o', color='y')
        plt.show()
    else:
        self.yellowLine.set_data([pickedXs.x], [pickedXs.y])
        self.fig.canvas.draw()
def plot(self)
Source code
def plot(self):
    for reach in self.reaches:
        if self.dem:
            contour_levels = np.arange(-2, 2, 0.1)
            self.ax.contourf(self.dem[0], self.dem[1], self.dem[2], contour_levels, cmap='terrain', zorder=0)
        self.ax.plot([p.x for p in reach.riverPoints], [p.y for p in reach.riverPoints], color='b', zorder=1)
        pathcoll = self.ax.scatter([p.x for p in reach.xss], [p.y for p in reach.xss], marker='o', color='b', picker=5)
        self.ax.scatter([xs.x for xs in reach.xss if xs.is_closed], [xs.y for xs in reach.xss if xs.is_closed], marker='o', color='green', zorder=2) #Marking xs which are closed
        self.ax.scatter([xs.x for xs in reach.xss if xs.is_weir], [xs.y for xs in reach.xss if xs.is_weir], marker='o', color='red', zorder=3)  # Marking xs which are weirs
        self.pathcolls.append(pathcoll)
        if self.show_perimenter_points is True:
            for reach in self.reaches:
                for xs in reach.xss:
                    self.ax.plot([pp.x for pp in xs.pps], [pp.y for pp in xs.pps], marker='x', color='green', zorder=0)

    if self.show:
        plt.show()
class ProfilePlot (reach=None, fig=None, position=111, showBanks=True, showWaterLevel=False, show=True, show_normal_depths=False)
Source code
class ProfilePlot():
    def __init__(self, reach=None, fig=None, position=111, showBanks=True, showWaterLevel = False, show=True, show_normal_depths=False):
        self.reach = reach
        self.position = position
        self.show = show
        self.showBanks = showBanks
        self.showWaterLevel = showWaterLevel
        self.show_normal_depths = show_normal_depths
        self.ax = None
        self.fig = fig
        self.yellowLine = None  # The yellow marker that indicates which crosssection that is selected.
        if self.fig is None:
            self.fig = plt.figure()
        self.ax = self.fig.add_subplot(self.position)
        self.plot()

    def plot(self):
        if self.reach != None:
            chainages = [xs.chainage for xs in self.reach.xss]
            zmins = [xs.z for xs in self.reach.xss]
            self.ax.plot(chainages, zmins, color='k', marker='o', zorder=1)
            self.ax.scatter([xs.chainage for xs in self.reach.xss if xs.is_closed], [xs.z for xs in self.reach.xss if xs.is_closed], marker='o', color='green', zorder=2)  # Marking xs which are closed
            self.ax.scatter([xs.chainage for xs in self.reach.xss if xs.is_weir], [xs.z for xs in self.reach.xss if xs.is_weir], marker='o', color='red', zorder=3)  # Marking xs which are weirs

            if self.showBanks:
                self.ax.plot(chainages, [xs.pps[0].dz + xs.z for xs in self.reach.xss], '--', color='k')
                self.ax.plot(chainages, [xs.pps[-1].dz + xs.z for xs in self.reach.xss], '--', color='k')

            if self.showWaterLevel:
                if len(self.reach.calculated_water_levels) == 0:
                    self.ax.plot(chainages, [xs.depth + xs.z for xs in self.reach.xss], color='b', zorder=10, label='calculated water level')
                else:
                    self.ax.plot([wl[0] for wl in self.reach.calculated_water_levels],[wl[1] for wl in self.reach.calculated_water_levels], color='b', zorder=10)

            # for observation in self.reach.observations:
            #     self.ax.scatter([a[0] for a in observation.chainage_waterlevels], [a[1] for a in observation.chainage_waterlevels], marker='o', color='red', label=observation.name, zorder=20)

            self.ax.scatter([a[0] for a in self.reach.observations], [a[1] for a in self.reach.observations], marker='o', color='red', label='Observed', zorder=20)

            if self.show_normal_depths:
                chs = []
                normal_depths = []
                for n in range(len(self.reach.xss) - 1):
                    slope = (self.reach.xss[n + 1].z - self.reach.xss[n].z) / (self.reach.xss[n + 1].chainage - self.reach.xss[n].chainage)
                    if slope > 0.:
                        chs.append((self.reach.xss[n].chainage + self.reach.xss[n + 1].chainage) / 2.)
                        z_mean = (self.reach.xss[n].z + self.reach.xss[n + 1].z) / 2.
                        normal_depths.append(z_mean + self.reach.xss[n].get_normal_depth(slope))
                self.ax.scatter(chs, normal_depths, marker='o', color='green', label='Normal depth')

            # if showLabels:
            #     for i, j in zip(chainages, zmins):
            #         ax.annotate('%s)' % j, xy=(i, j), xytext=(30, 0), textcoords='offset points')
            #         ax.annotate('(%s,' % i, xy=(i, j))
            #
            # if showGrid:
            #     ax.grid()
            self.ax.legend()

            self.ax.set_title(self.reach.name)
            self.fig.canvas.draw()
            if self.show is True:
                plt.show()

    def update(self, reach, xs):
        # if reach != self.reach: TODO: linjerne er udkommenteret da det ellers ikke virker, men figuren flikker...
            self.ax.clear()
            self.reach = reach
            self.yellowLine, = self.ax.plot([xs.chainage],[xs.z], marker='o', color='y', linestyle=' ', zorder=3)
            self.plot()

Methods

def plot(self)
Source code
def plot(self):
    if self.reach != None:
        chainages = [xs.chainage for xs in self.reach.xss]
        zmins = [xs.z for xs in self.reach.xss]
        self.ax.plot(chainages, zmins, color='k', marker='o', zorder=1)
        self.ax.scatter([xs.chainage for xs in self.reach.xss if xs.is_closed], [xs.z for xs in self.reach.xss if xs.is_closed], marker='o', color='green', zorder=2)  # Marking xs which are closed
        self.ax.scatter([xs.chainage for xs in self.reach.xss if xs.is_weir], [xs.z for xs in self.reach.xss if xs.is_weir], marker='o', color='red', zorder=3)  # Marking xs which are weirs

        if self.showBanks:
            self.ax.plot(chainages, [xs.pps[0].dz + xs.z for xs in self.reach.xss], '--', color='k')
            self.ax.plot(chainages, [xs.pps[-1].dz + xs.z for xs in self.reach.xss], '--', color='k')

        if self.showWaterLevel:
            if len(self.reach.calculated_water_levels) == 0:
                self.ax.plot(chainages, [xs.depth + xs.z for xs in self.reach.xss], color='b', zorder=10, label='calculated water level')
            else:
                self.ax.plot([wl[0] for wl in self.reach.calculated_water_levels],[wl[1] for wl in self.reach.calculated_water_levels], color='b', zorder=10)

        # for observation in self.reach.observations:
        #     self.ax.scatter([a[0] for a in observation.chainage_waterlevels], [a[1] for a in observation.chainage_waterlevels], marker='o', color='red', label=observation.name, zorder=20)

        self.ax.scatter([a[0] for a in self.reach.observations], [a[1] for a in self.reach.observations], marker='o', color='red', label='Observed', zorder=20)

        if self.show_normal_depths:
            chs = []
            normal_depths = []
            for n in range(len(self.reach.xss) - 1):
                slope = (self.reach.xss[n + 1].z - self.reach.xss[n].z) / (self.reach.xss[n + 1].chainage - self.reach.xss[n].chainage)
                if slope > 0.:
                    chs.append((self.reach.xss[n].chainage + self.reach.xss[n + 1].chainage) / 2.)
                    z_mean = (self.reach.xss[n].z + self.reach.xss[n + 1].z) / 2.
                    normal_depths.append(z_mean + self.reach.xss[n].get_normal_depth(slope))
            self.ax.scatter(chs, normal_depths, marker='o', color='green', label='Normal depth')

        # if showLabels:
        #     for i, j in zip(chainages, zmins):
        #         ax.annotate('%s)' % j, xy=(i, j), xytext=(30, 0), textcoords='offset points')
        #         ax.annotate('(%s,' % i, xy=(i, j))
        #
        # if showGrid:
        #     ax.grid()
        self.ax.legend()

        self.ax.set_title(self.reach.name)
        self.fig.canvas.draw()
        if self.show is True:
            plt.show()
def update(self, reach, xs)
Source code
def update(self, reach, xs):
    # if reach != self.reach: TODO: linjerne er udkommenteret da det ellers ikke virker, men figuren flikker...
        self.ax.clear()
        self.reach = reach
        self.yellowLine, = self.ax.plot([xs.chainage],[xs.z], marker='o', color='y', linestyle=' ', zorder=3)
        self.plot()
class XssPlot (xss=[], fig=None, position=111, show=False, showWaterLevel=False)
Source code
class XssPlot():
    def __init__(self, xss = [], fig=None, position=111, show=False, showWaterLevel=False):
        self.xss = xss
        self.position = position
        self.show = show
        self.showWaterLevel = showWaterLevel
        self.ax = None
        self.fig = fig
        if self.fig == None:
            self.fig = plt.figure()
        self.ax = self.fig.add_subplot(self.position)
        self.fig.canvas.mpl_connect('key_press_event', self.press)
        self.plot()
        print('XssPlot __init__(...) completed.')

    def press(self, event):
        if event.key == 'escape':
            lastXs = self.xss[-1]
            self.xss = [lastXs]
            self.ax.clear()
            self.plot()

    def plot(self):
        if len(self.xss) > 0:
            for n in range(len(self.xss) - 1):
                xp, zp = [p.dx for p in self.xss[n].pps], [p.dz + self.xss[n].z for p in self.xss[n].pps]
                self.ax.plot(xp, zp, color='gray', zorder=0)
                self.ax.scatter(xp, zp, color='gray', zorder=0)

            self.ax.plot([p.dx for p in self.xss[-1].pps], [p.dz + self.xss[-1].z for p in self.xss[-1].pps], color='k', zorder=1)
            self.ax.scatter([p.dx for p in self.xss[-1].pps], [p.dz + self.xss[-1].z for p in self.xss[-1].pps], color='k', zorder=1)

            leftbank_points = [p for p in self.xss[-1].pps if p.marker == 'left bank']
            self.ax.scatter([p.dx for p in leftbank_points], [p.dz + self.xss[-1].z for p in leftbank_points], color='r', marker='o', zorder=2)
            rightbank_points = [p for p in self.xss[-1].pps if p.marker == 'right bank']
            self.ax.scatter([p.dx for p in rightbank_points], [p.dz + self.xss[-1].z for p in rightbank_points], color='b', marker='o',zorder=2)
            center_points = [p for p in self.xss[-1].pps if p.marker == 'center']
            self.ax.scatter([p.dx for p in center_points], [p.dz + self.xss[-1].z for p in center_points], color='y', marker='o',zorder=2)

            if self.showWaterLevel:
                wps = self.xss[-1].get_wetted_polygon(self.xss[-1].depth)
                self.ax.fill([p.dx for p in wps], [p.dz + self.xss[-1].z for p in wps], zorder=0)

            if self.xss[-1].is_closed:
                is_closed_str = 'closed xs'
            else:
                is_closed_str = 'open xs'
            self.ax.set_title('Chainage: ' + str(self.xss[-1].chainage) + ' ' + is_closed_str)
            self.fig.canvas.draw()

            if self.show:
                plt.show()

    def update(self, xs):
        self.ax.clear()
        while xs in self.xss:
            self.xss.remove(xs)

        self.xss.append(xs)

        print('updated XssPlot')
        self.plot()

Methods

def plot(self)
Source code
def plot(self):
    if len(self.xss) > 0:
        for n in range(len(self.xss) - 1):
            xp, zp = [p.dx for p in self.xss[n].pps], [p.dz + self.xss[n].z for p in self.xss[n].pps]
            self.ax.plot(xp, zp, color='gray', zorder=0)
            self.ax.scatter(xp, zp, color='gray', zorder=0)

        self.ax.plot([p.dx for p in self.xss[-1].pps], [p.dz + self.xss[-1].z for p in self.xss[-1].pps], color='k', zorder=1)
        self.ax.scatter([p.dx for p in self.xss[-1].pps], [p.dz + self.xss[-1].z for p in self.xss[-1].pps], color='k', zorder=1)

        leftbank_points = [p for p in self.xss[-1].pps if p.marker == 'left bank']
        self.ax.scatter([p.dx for p in leftbank_points], [p.dz + self.xss[-1].z for p in leftbank_points], color='r', marker='o', zorder=2)
        rightbank_points = [p for p in self.xss[-1].pps if p.marker == 'right bank']
        self.ax.scatter([p.dx for p in rightbank_points], [p.dz + self.xss[-1].z for p in rightbank_points], color='b', marker='o',zorder=2)
        center_points = [p for p in self.xss[-1].pps if p.marker == 'center']
        self.ax.scatter([p.dx for p in center_points], [p.dz + self.xss[-1].z for p in center_points], color='y', marker='o',zorder=2)

        if self.showWaterLevel:
            wps = self.xss[-1].get_wetted_polygon(self.xss[-1].depth)
            self.ax.fill([p.dx for p in wps], [p.dz + self.xss[-1].z for p in wps], zorder=0)

        if self.xss[-1].is_closed:
            is_closed_str = 'closed xs'
        else:
            is_closed_str = 'open xs'
        self.ax.set_title('Chainage: ' + str(self.xss[-1].chainage) + ' ' + is_closed_str)
        self.fig.canvas.draw()

        if self.show:
            plt.show()
def press(self, event)
Source code
def press(self, event):
    if event.key == 'escape':
        lastXs = self.xss[-1]
        self.xss = [lastXs]
        self.ax.clear()
        self.plot()
def update(self, xs)
Source code
def update(self, xs):
    self.ax.clear()
    while xs in self.xss:
        self.xss.remove(xs)

    self.xss.append(xs)

    print('updated XssPlot')
    self.plot()