# Path: pytripgui/canvas_vc/objects/vdx.py
# class Vdx:
#     """
#     This class holds data model for plotting Vdx stuff.
#     """
#     def __init__(self, ctx, projection_selector):
#         self.ctx = ctx
#         self.projection_selector = projection_selector
#         self.voi_list = []
# 
# Path: pytripgui/canvas_vc/plotter/managers/blit_manager.py
# class BlitManager:
#     def __init__(self, canvas, animated_artists=()):
#         """
#         Parameters
#         ----------
#         canvas : FigureCanvasAgg
#             The canvas to work with, this only works for sub-classes of the Agg
#             canvas which have the `~FigureCanvasAgg.copy_from_bbox` and
#             `~FigureCanvasAgg.restore_region` methods.
# 
#         animated_artists : Iterable[Artist]
#             List of the artists to manage
#         """
#         self.canvas = canvas
#         self._bg = None
#         self._artists = []
# 
#         for a in animated_artists:
#             self.add_artist(a)
#         # grab the background on every draw
#         self.cid = canvas.mpl_connect("draw_event", self.on_draw)
# 
#     def on_draw(self, event):
#         """Callback to register with 'draw_event'."""
#         cv = self.canvas
#         if event is not None and event.canvas != cv:
#             raise RuntimeError
#         self._bg = cv.copy_from_bbox(cv.figure.bbox)
#         self._draw_animated()
# 
#     def add_artist(self, art):
#         """
#         Add an artist to be managed.
# 
#         Parameters
#         ----------
#         art : Artist
# 
#             The artist to be added.  Will be set to 'animated' (just
#             to be safe).  *art* must be in the figure associated with
#             the canvas this class is managing.
# 
#         """
#         if art.figure != self.canvas.figure:
#             raise RuntimeError
#         art.set_animated(True)
#         self._artists.append(art)
# 
#     def remove_artist(self, art):
#         """
#         Remove an artist.
# 
#         Parameters
#         ----------
#         art : Artist
# 
#             The artist to be removed.
#             *art* must be in the figure associated with
#             the canvas this class is managing.
# 
#         """
#         if art.figure != self.canvas.figure:
#             raise RuntimeError
#         self._artists.remove(art)
# 
#     def _draw_animated(self):
#         """Draw all of the animated artists."""
#         fig = self.canvas.figure
#         for a in self._artists:
#             fig.draw_artist(a)
# 
#     def update(self):
#         """Update the screen with animated artists."""
#         cv = self.canvas
#         fig = cv.figure
#         # paranoia in case we missed the draw event,
#         if self._bg is None:
#             self.on_draw(None)
#         else:
#             # restore the background
#             cv.restore_region(self._bg)
#             # draw all of the animated artists
#             self._draw_animated()
#             # update the GUI state
#             cv.blit(fig.bbox)
#         # let the GUI event loop process anything it has to do
#         cv.flush_events()


import logging
import matplotlib.colors
import numpy as np
from typing import Optional, Dict, List
from matplotlib.axes import Axes
from matplotlib.lines import Line2D
from pytrip.vdx import Slice, Voi
from pytripgui.canvas_vc.objects.vdx import Vdx
from pytripgui.canvas_vc.plotter.managers import BlitManager

        self._axes.text(x1,
                        y1 - 0.025 * height,
                        legend,
                        color=bright_color,
                        va="top",
                        fontsize=7,
                        weight='semibold',
                        backgroundcolor=(0.0, 0.0, 0.0, 0.8),
                        zorder=20)  # zorder higher, so text is always above the lines
        self._axes.plot(x, y, 'o', color=color, zorder=15)  # plot the dot

    def remove_voi(self) -> None:
        names = list(self._plotted_voi.keys())
        for name in names:
            self._remove_all_voi_plots(name)

    def _remove_all_voi_plots(self, name: str) -> None:
        for line in self._plotted_voi[name]:
            self._blit_manager.remove_artist(line)
            line.remove()

        del self._plotted_voi[name]

    @staticmethod
    def _get_color(voi: Voi) -> (float, float, float):
        # color in voi is stored as [a, b, c] where a,b,c are numbers from 0 to 255
        # dividing by 255.0 to have float values from 0.0 to 1.0 to adapt to matplotlib colors
        color = tuple(c / 255.0 for c in voi.get_color())
        return color


# Path: pytripgui/canvas_vc/objects/vdx.py
# class Vdx:
#     """
#     This class holds data model for plotting Vdx stuff.
#     """
#     def __init__(self, ctx, projection_selector):
#         self.ctx = ctx
#         self.projection_selector = projection_selector
#         self.voi_list = []
# 
# Path: pytripgui/canvas_vc/plotter/managers/blit_manager.py
# class BlitManager:
#     def __init__(self, canvas, animated_artists=()):
#         """
#         Parameters
#         ----------
#         canvas : FigureCanvasAgg
#             The canvas to work with, this only works for sub-classes of the Agg
#             canvas which have the `~FigureCanvasAgg.copy_from_bbox` and
#             `~FigureCanvasAgg.restore_region` methods.
# 
#         animated_artists : Iterable[Artist]
#             List of the artists to manage
#         """
#         self.canvas = canvas
#         self._bg = None
#         self._artists = []
# 
#         for a in animated_artists:
#             self.add_artist(a)
#         # grab the background on every draw
#         self.cid = canvas.mpl_connect("draw_event", self.on_draw)
# 
#     def on_draw(self, event):
#         """Callback to register with 'draw_event'."""
#         cv = self.canvas
#         if event is not None and event.canvas != cv:
#             raise RuntimeError
#         self._bg = cv.copy_from_bbox(cv.figure.bbox)
#         self._draw_animated()
# 
#     def add_artist(self, art):
#         """
#         Add an artist to be managed.
# 
#         Parameters
#         ----------
#         art : Artist
# 
#             The artist to be added.  Will be set to 'animated' (just
#             to be safe).  *art* must be in the figure associated with
#             the canvas this class is managing.
# 
#         """
#         if art.figure != self.canvas.figure:
#             raise RuntimeError
#         art.set_animated(True)
#         self._artists.append(art)
# 
#     def remove_artist(self, art):
#         """
#         Remove an artist.
# 
#         Parameters
#         ----------
#         art : Artist
# 
#             The artist to be removed.
#             *art* must be in the figure associated with
#             the canvas this class is managing.
# 
#         """
#         if art.figure != self.canvas.figure:
#             raise RuntimeError
#         self._artists.remove(art)
# 
#     def _draw_animated(self):
#         """Draw all of the animated artists."""
#         fig = self.canvas.figure
#         for a in self._artists:
#             fig.draw_artist(a)
# 
#     def update(self):
#         """Update the screen with animated artists."""
#         cv = self.canvas
#         fig = cv.figure
#         # paranoia in case we missed the draw event,
#         if self._bg is None:
#             self.on_draw(None)
#         else:
#             # restore the background
#             cv.restore_region(self._bg)
#             # draw all of the animated artists
#             self._draw_animated()
#             # update the GUI state
#             cv.blit(fig.bbox)
#         # let the GUI event loop process anything it has to do
#         cv.flush_events()


# Path: pytripgui/canvas_vc/plotter/managers/voi_manager.py
import logging
import matplotlib.colors
import numpy as np
from typing import Optional, Dict, List
from matplotlib.axes import Axes
from matplotlib.lines import Line2D
from pytrip.vdx import Slice, Voi
from pytripgui.canvas_vc.objects.vdx import Vdx
from pytripgui.canvas_vc.plotter.managers import BlitManager

        self._axes.text(x1,
                        y1 - 0.025 * height,
                        legend,
                        color=bright_color,
                        va="top",
                        fontsize=7,
                        weight='semibold',
                        backgroundcolor=(0.0, 0.0, 0.0, 0.8),
                        zorder=20)  # zorder higher, so text is always above the lines
        self._axes.plot(x, y, 'o', color=color, zorder=15)  # plot the dot

    def remove_voi(self) -> None:
        names = list(self._plotted_voi.keys())
        for name in names:
            self._remove_all_voi_plots(name)

    def _remove_all_voi_plots(self, name: str) -> None:
        for line in self._plotted_voi[name]:
            self._blit_manager.remove_artist(line)
            line.remove()

        del self._plotted_voi[name]

    @staticmethod
    def _get_color(voi: Voi) -> (float, float, float):
        # color in voi is stored as [a, b, c] where a,b,c are numbers from 0 to 255
        # dividing by 255.0 to have float values from 0.0 to 1.0 to adapt to matplotlib colors
        color = tuple(c / 255.0 for c in voi.get_color())
        return color


    def _get_plot_data(self, vdx: Vdx, data):
