#
#coding=utf-8
#Copyright (C) 2015 Barcelona Science
#
#This program is free software; you can redistribute it and/or modify it under the terms of the 
#GNU General Public License as published by the Free Software Foundation; either version 2 of the License, 
#or (at your option) any later version. This program is distributed in the hope that it will be useful, but 
#WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
#PURPOSE. See the GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License along with this program; if not, write to 
#the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
:copyright: Copyright (C) 2015 Barcelona Science
:authors: L.M. de Vries, A. Nardi
:contact: enric.vazquez@idaea.csic.es
:license: GPL General Public License, version 2 or any later version (http://opensource.org/licenses/GPL-2.0)
'''
from collections import OrderedDict
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt
import sys
from PyQt4 import QtGui
import math
from matplotlib.lines import Line2D
import numpy

from ChemPlot import ChemPlot
from ChemPlot import CPSETTINGS
from ChemPlot import LINESERIES

class PIPERSETTINGS():    
    piper = "piper"
    
    pane_separation_id = "pane_separation"    
    pane_surface_color_id = "pane_surface_color"
    pane_border_color_id= "pane_border_color"
    
    grid_divisions_id = "grid_divisions"    
    grid_line_style_id = "grid_line_style"
    grid_line_color_id = "grid_line_color"
    grid_line_thickness_id = "grid_line_thickness"
    
    subgrid_divisions_id = "subgrid_divisions"    
    subgrid_line_style_id = "subgrid_line_style"
    subgrid_line_color_id = "subgrid_line_color"
    subgrid_line_thickness_id = "subgrid_line_thickness"

    font_axes_labels_size_id = "font_axes_labels_size"    
    font_corners_labels_size_id = "font_corners_labels_size"
    font_grid_labels_size_id = "font_grid_labels_size"
    
    default_settings = OrderedDict({
                piper:{
                    pane_separation_id:{
                        CPSETTINGS.value_key:25.5,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"float"
                    },
                    pane_surface_color_id:{
                        CPSETTINGS.value_key: "white",
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"str"
                    },
                    pane_border_color_id:{
                        CPSETTINGS.value_key: "black",
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"str"
                    },
                    grid_divisions_id:{
                        CPSETTINGS.value_key:4,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"int"
                    },
                    grid_line_style_id:{
                        CPSETTINGS.value_key: "solid",
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"str"
                    },
                    grid_line_color_id:{
                        CPSETTINGS.value_key: "#A2A2A2",
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"str"
                    },
                    grid_line_thickness_id:{
                        CPSETTINGS.value_key: 1.0,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"float"
                    },
                    subgrid_divisions_id:{
                        CPSETTINGS.value_key:3,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"int"
                    },
                    subgrid_line_style_id:{
                        CPSETTINGS.value_key: "solid",
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"str"
                    },
                    subgrid_line_color_id:{
                        CPSETTINGS.value_key: "#A9A9A9",
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"str"
                    },
                    subgrid_line_thickness_id:{
                        CPSETTINGS.value_key: 0.4,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"float"
                    },
                    font_axes_labels_size_id:{
                        CPSETTINGS.value_key: 13.0,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"float"
                    },
                    font_corners_labels_size_id:{
                        CPSETTINGS.value_key: 12.0,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"float"
                    },
                    font_grid_labels_size_id:{
                        CPSETTINGS.value_key: 10.0,
                        CPSETTINGS.label_key:"",
                        CPSETTINGS.type_value_key:"float"
                    }
                }
            })

class PiperPlot(ChemPlot):
    '''
    This class implements the Piper plot. The Piper plot represents the cations-anions percentage relationships in 
    different panes. 
    '''

    def __init__(self, parent=None):
        self.m_settings = {}
        super(PiperPlot, self).__init__(parent)
        
        self.labels = []
        self.CE = []
        self.Cations = []       
        
        self.rotated_labels = []
        
        self.legendPosition = 'PiperLegend'
        
        self.m_settings.update(PIPERSETTINGS.default_settings)        
       
        self.set_setting(CPSETTINGS.title, CPSETTINGS.title_label_id, 'Piper Plot')
        self.set_setting(CPSETTINGS.window, CPSETTINGS.window_title_id, 'Piper')
        self.set_setting(CPSETTINGS.line_plot, CPSETTINGS.line_show_id, False)        
        self.set_setting(CPSETTINGS.line_plot, CPSETTINGS.line_width_id, 0.5)
        self.set_setting(CPSETTINGS.line_plot, CPSETTINGS.line_type_serie_id, LINESERIES.dashed)

    def setData(self, labels, values):        
        #values = {'Ca':[], 'Mg':[], 'NaK':[], 'HCO3CO3':[], 'Mg':[], 'NaK':[]}
        self.labels = labels
        self.Ca = values['Ca']
        self.Mg = values['Mg']
        self.NaK = values['NaK']
        self.HCO3CO3 = values['HCO3CO3']
        self.SO4 = values['SO4']
        self.Cl = values['Cl']
    
    def pre_processing(self):
        self.length = 100 
        self.space = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.pane_separation_id)        
        self.faceColor = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.pane_surface_color_id)
        self.edgeColor = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.pane_border_color_id)

        self.gridDivisions =  self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.grid_divisions_id)+1
        self.gridLineStyle = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.grid_line_style_id)
        self.gridLineColor = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.grid_line_color_id)
        self.gridLineThickness = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.grid_line_thickness_id)

        self.gridSubDivisions = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.subgrid_divisions_id)+1       
        self.subGridLineStyle = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.subgrid_line_style_id)
        self.subGridLineColor = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.subgrid_line_color_id)
        self.subGridLineThickness = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.subgrid_line_thickness_id)
        
        self.fontSizeLabel = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.font_axes_labels_size_id)
        self.fontSizeCorners = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.font_corners_labels_size_id)
        self.fontSizeGrid = self.setting(PIPERSETTINGS.piper, PIPERSETTINGS.font_grid_labels_size_id)
        
        patches = []
        self.factorH = math.sqrt(3)/2
        factorH = self.factorH        
        self.height = factorH*self.length
        self.smallHeight = factorH*self.space
                
        length = self.length        
        space = self.space
        height = self.height
        smallHeight = self.smallHeight
        
        # left triangle
        coords = [[0,0],[length,0],[length/2,height]]
        polygon = Polygon(coords, True)
        patches.append(polygon)
        
        # right triangle
        coords = [[length+space,0],[2*length+space,0],[3*length/2+space,height]]
        polygon = Polygon(coords, True)
        patches.append(polygon)
        
        # top triangle
        coords = [[length+space/2,smallHeight],[3*length/2+space/2,smallHeight+height],[length+space/2,smallHeight+2*height],[length/2+space/2,smallHeight+height]]
        polygon = Polygon(coords, True)
        patches.append(polygon)
        
        # add polygons
        p = PatchCollection(patches, alpha=1.0)   
        p.set_facecolor(self.faceColor) 
        p.set_edgecolor(self.edgeColor)     
        self.ax.add_collection(p)
        
        corners = {'top':'Mg', 'left': 'Ca', 'right': 'Na+K'}
    
        labelInfo ={ 'bottom':{'label': r' Ca (%meq)', 'orientation': 'toLeft'},
        'left':{'label': r'Mg (%meq)', 'orientation': 'toRight'},
        'right':{'label': r'Na+K (%meq)', 'orientation': 'toRight'}}
            
        self.drawGridAndLabelsInTriangle(0, labelInfo, corners)
        
        corners = {'top':'SO4', 'left': 'HCO3 + CO3', 'right': 'Cl'}
    
        labelInfo ={ 'bottom':{'label': r'Cl (%meq)', 'orientation': 'toRight'},
        'right':{'label': r'SO4 (%meq)', 'orientation': 'toLeft'},
        'left':{'label': r'HCO3+CO3 (%meq)', 'orientation': 'toLeft'}}        
        self.drawGridAndLabelsInTriangle(1,  labelInfo, corners)
        
        labelInfo ={ 'topLeft':{'label': r'SO4+Cl (%meq)', 'orientation': 'toLeft'},
        'topRight':{'label': r'Ca+Mg (%meq)', 'orientation': 'toRight'}}        
        
        self.drawGridAndLabelsInSquare(labelInfo)
        
    def post_processing(self):
        
        length = self.length
        
        space = self.space
        height = self.height
        smallHeight = self.smallHeight
        
        self.ax.axis([-space/20, 2*length+space, -space/20, 2*height+smallHeight])
        plt.axis('off')
        
        self.fig.canvas.mpl_connect('resize_event', self.updateTextsOnLayers)
        
    def drawGridAndLabelsInTriangle(self, position, labelInfo, corners):
        length = float(self.length)
        space = float(self.space)
        gridDivisions = self.gridDivisions
        gridSubDivisions = self.gridSubDivisions
        factorH = self.factorH
        fontSizeLabel = self.fontSizeLabel
        fontSizeGrid = self.fontSizeGrid  
        height = self.height
        
        iniX = 0
        sign = 1
        if(position == 1):
            iniX = length + space
            sign = -1
            pass
        
        # add grid to triangles
        for i in range(1, gridDivisions+1, 1):
            for j in range(0, gridSubDivisions, 1):
            
                x_i = length/gridDivisions*(float(i)-float(j)/gridSubDivisions)
                
                lineStyle = self.subGridLineStyle
                lineThickness = self.subGridLineThickness
                lineColor = self.subGridLineColor
                if j == 0 and i<gridDivisions:                    
                    lineStyle = self.gridLineStyle
                    lineThickness = self.gridLineThickness
                    lineColor = self.gridLineColor
                
                
                curLength = (length - x_i)/2
                line = Line2D([iniX+x_i,iniX+x_i+curLength],[0,(2*curLength)*factorH], linestyle=lineStyle, linewidth=lineThickness, color=lineColor)
                self.ax.add_line(line)
                
                curLength = (x_i)/2
                line = Line2D([iniX+x_i,iniX+x_i-curLength],[0,(2*curLength)*factorH], linestyle=lineStyle, linewidth=lineThickness, color=lineColor)
                self.ax.add_line(line)
                
                curLength = length - x_i
                line = Line2D([iniX+(x_i)/2,iniX+(x_i)/2+curLength],[x_i*factorH,x_i*factorH], linestyle=lineStyle, linewidth=lineThickness, color=lineColor)
                self.ax.add_line(line)
        
        # add labels
        line1 = Line2D([iniX+0, iniX + length],[0, 0])
        labelToAdd = labelInfo['bottom']['label']
        xdata, ydata = line1.get_data()
        x1 = xdata[0]
        x2 = xdata[-1]
        y1 = ydata[0]
        y2 = ydata[-1]
        centerX = x1+(x2-x1)/2
        centerY = -8
        fontsize= fontSizeLabel
        p1 = numpy.array((x1, y1))
        p2 = numpy.array((x2, y2))
        sp1 = self.ax.transData.transform_point(p1)
        sp2 = self.ax.transData.transform_point(p2)
        rise = (sp2[1] - sp1[1])
        run = (sp2[0] - sp1[0])
        slope_degrees_1 = math.degrees(math.atan(rise/run))
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='top', rotation=slope_degrees_1)
        self.rotated_labels.append({"text":myText, "line":line1, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
        
        labelToAdd =  corners['left']
        centerX = iniX
        centerY = -1
        fontsize=self.fontSizeCorners
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='top', rotation=slope_degrees_1)
        self.rotated_labels.append({"text":myText, "line":line1, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
        
        labelToAdd =  corners['top']
        centerX = iniX+length/2 
        centerY = height + 2
        fontsize=self.fontSizeCorners
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='bottom', rotation=slope_degrees_1)
        self.rotated_labels.append({"text":myText, "line":line1, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
        
        labelToAdd =  corners['right']
        centerX = iniX+length
        centerY = 0 -1
        fontsize=self.fontSizeCorners
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='top', rotation=slope_degrees_1)
        self.rotated_labels.append({"text":myText, "line":line1, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})            
        
        # Outside horizontal labels
        myRange = range(1, gridDivisions, 1)
        for i in myRange:                       
            labelToAdd = str(int(round(float(i)*100/gridDivisions,0)))
            centerX = iniX -sign*2 + position*length+sign*length/(gridDivisions)*float(i)/2
            centerY = height/(gridDivisions)*float(i)-0.5
            fontsize=fontSizeGrid
            horizontalAlign = 'right'
            
            if(position == 1):
                horizontalAlign = 'left'            
            myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment=horizontalAlign, verticalalignment='center', rotation=slope_degrees_1)
                              
            self.rotated_labels.append({"text":myText, "line":line1, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
        
        line2 = Line2D([iniX+0, iniX + length/2],[0, height])
        labelToAdd = labelInfo['left']['label']
        xdata, ydata = line2.get_data()
        x1 = xdata[0]
        x2 = xdata[-1]
        y1 = ydata[0]
        y2 = ydata[-1]
        
        centerX =x1+(x2-x1)/2-4
        centerY =y1+(y2-y1)/2-2
        if position == 1:
            centerX =x1+(x2-x1)/2-2
            centerY =y1+(y2-y1)/2-4
        fontsize=fontSizeLabel
        p1 = numpy.array((x1, y1))
        p2 = numpy.array((x2, y2))
        sp1 = self.ax.transData.transform_point(p1)
        sp2 = self.ax.transData.transform_point(p2)
        rise = (sp2[1] - sp1[1])
        run = (sp2[0] - sp1[0])
        slope_degrees_2 = math.degrees(math.atan(rise/run))
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='bottom', rotation=slope_degrees_2) 
        self.rotated_labels.append({"text":myText, "line":line2, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})

        # interior        
        myRange = range(1, gridDivisions, 1)
        counter = 1
        for i in myRange:
                        
            labelToAdd = str(int(round(float(i)*100/gridDivisions,0)))
            
            centerX = iniX  + (1-position)*length/2 +length/(gridDivisions)*float(i)/(2-position)
            centerY = (1-position)*height-(1-position)*height/(gridDivisions)*float(i)+sign*2
            fontsize=fontSizeGrid
            horizontalAlign = 'left'
            verticalalignment = 'bottom'
            if(position == 1):
                horizontalAlign = 'right'
                verticalalignment = 'top'
                labelToAdd = str(int(round(float(i)*100/gridDivisions,0)))       
            
            counter += 1    
            myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment=horizontalAlign, verticalalignment=verticalalignment, rotation=slope_degrees_2)

            self.rotated_labels.append({"text":myText, "line":line2, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
        
        line3 = Line2D([iniX + length/2, iniX +  length],[height, 0])
        labelToAdd = labelInfo['right']['label']
        xdata, ydata = line3.get_data()
        x1 = xdata[0]
        x2 = xdata[-1]
        y1 = ydata[0]
        y2 = ydata[-1]
        centerX =x1+(x2-x1)/2 +2
        centerY =y1+(y2-y1)/2 -2
        fontsize=fontSizeLabel
        p1 = numpy.array((x1, y1))
        p2 = numpy.array((x2, y2))
        sp1 = self.ax.transData.transform_point(p1)
        sp2 = self.ax.transData.transform_point(p2)
        run = (sp2[0] - sp1[0])
        slope_degrees_3 = math.degrees(math.atan(rise/run))
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='bottom', rotation=slope_degrees_3) 
        self.rotated_labels.append({"text":myText, "line":line3, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})  
        
        myRange = range(1, gridDivisions, 1)
        counter = 1
        for i in myRange:
            labelToAdd = str(int(round(100-float(i)*100/gridDivisions,0)))
            
            centerX = iniX + length/(gridDivisions)*float(i)/(1+position) 
            centerY = position*height/(gridDivisions)*float(i)-sign*2
            fontsize=fontSizeGrid
            horizontalAlign = 'left'
            verticalalignment = 'top'
            if(position == 1):
                horizontalAlign = 'right'
                verticalalignment = 'bottom'
            counter += 1            
            myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment=horizontalAlign, verticalalignment=verticalalignment, rotation=slope_degrees_3)

            self.rotated_labels.append({"text":myText, "line":line3, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
    
    def drawGridAndLabelsInSquare(self, labelInfo):
        length = float(self.length)
        space = float(self.space)
        gridDivisions = self.gridDivisions
        factorH = self.factorH
        fontSizeLabel = self.fontSizeLabel
        fontSizeGrid = self.fontSizeGrid  
        height = self.height
        smallHeight = self.smallHeight
        gridSubDivisions = self.gridSubDivisions

        # add grid to rectangle    
        for i in range(0, gridDivisions, 1):
            for j in range(0, gridSubDivisions, 1):               
                xAdd = (length/gridDivisions)*0.5*(float(i)+float(j)/gridSubDivisions)
                yAdd = (length/gridDivisions)*factorH*(float(i)+float(j)/gridSubDivisions)
                
                lineStyle = self.subGridLineStyle
                lineThickness = self.subGridLineThickness
                lineColor = self.subGridLineColor
                if j == 0 and i>0:
                    lineStyle = self.gridLineStyle
                    lineThickness = self.gridLineThickness
                    lineColor = self.gridLineColor
                                    
                line = Line2D([length + space/2-xAdd,3*length/2+space/2-xAdd],[smallHeight+yAdd,smallHeight+height+yAdd], linestyle=lineStyle, linewidth=lineThickness, color=lineColor)
                self.ax.add_line(line)
                
                line = Line2D([length+space/2+xAdd,length/2+space/2+xAdd],[smallHeight+yAdd,smallHeight+height+yAdd], linestyle=lineStyle, linewidth=lineThickness, color=lineColor)
                self.ax.add_line(line)
        
        labelToAdd = labelInfo['topLeft']['label']
        
        xAdd = (length)*0.5
        yAdd = (length)*factorH
        line = Line2D([length + space/2 - xAdd,length + space/2 ],[smallHeight+height,smallHeight+2*height], linestyle='solid', linewidth='2', color='g')
        xdata, ydata = line.get_data()
        x1 = xdata[0]
        x2 = xdata[-1]
        y1 = ydata[0]
        y2 = ydata[-1]
        centerX =x1+(x2-x1)/2 -4
        centerY =y1+(y2-y1)/2 -4 
        fontsize=fontSizeLabel
        p1 = numpy.array((x1, y1))
        p2 = numpy.array((x2, y2))
        sp1 = self.ax.transData.transform_point(p1)
        sp2 = self.ax.transData.transform_point(p2)
        rise = (sp2[1] - sp1[1])
        run = (sp2[0] - sp1[0])
        slope_degrees = math.degrees(math.atan(rise/run))
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='bottom', rotation=slope_degrees) 
        self.rotated_labels.append({"text":myText, "line":line, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
        
        myRange = range(1, gridDivisions, 1)
        for i in myRange:
            
            labelToAdd = str(int(round(100-float(i)*100/gridDivisions, 0)))
            centerX =  length + space/2 + length/(gridDivisions)*float(i)*0.5 +1
            centerY = smallHeight+2*height-height/(gridDivisions)*float(i) +1
            fontsize=fontSizeGrid
            myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='left', verticalalignment='bottom', rotation=slope_degrees)
            self.rotated_labels.append({"text":myText, "line":line, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
            
        labelToAdd = labelInfo['topRight']['label']
        
        xAdd = (length)*0.5
        yAdd = (length)*factorH
        line = Line2D([length + space/2,length + xAdd+ space/2 ],[smallHeight+2*height,smallHeight+height], linestyle='solid', linewidth='2', color='g')
        xdata, ydata = line.get_data()
        x1 = xdata[0]
        x2 = xdata[-1]
        y1 = ydata[0]
        y2 = ydata[-1]
        centerX =x1+(x2-x1)/2 +4 
        centerY =y1+(y2-y1)/2 -4 
        fontsize=fontSizeLabel
        p1 = numpy.array((x1, y1))
        p2 = numpy.array((x2, y2))
        sp1 = self.ax.transData.transform_point(p1)
        sp2 = self.ax.transData.transform_point(p2)
        rise = (sp2[1] - sp1[1])
        run = (sp2[0] - sp1[0])
        slope_degrees = math.degrees(math.atan(rise/run))
        myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='center', verticalalignment='bottom', rotation=slope_degrees) 
        self.rotated_labels.append({"text":myText, "line":line, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
                
        myRange = range(1, gridDivisions, 1)
        for i in myRange:
            labelToAdd =  str(int(round(float(i)*100/gridDivisions, 0)))
            centerX =  length + space/2 -length*0.5  + length/(gridDivisions)*float(i)*0.5 -1
            centerY = smallHeight+height+height/(gridDivisions)*float(i) -1
            fontsize=fontSizeGrid
            myText = self.ax.text(centerX, centerY, labelToAdd, fontsize=fontsize, horizontalalignment='right', verticalalignment='bottom', rotation=slope_degrees)
            self.rotated_labels.append({"text":myText, "line":line, "p1":numpy.array((x1, y1)), "p2":numpy.array((x2, y2))})
               
    def plot_values(self):
        iniX = self.length + self.space
        iniXHalf = self.length + self.space/2
        
        
        for curPoint in range(len(self.labels)): 
            x1 = self.length*((100-self.Ca[curPoint])/100*0.5+(self.NaK[curPoint]/100)*0.5)
            y1 = self.length*((self.Mg[curPoint]/100)*self.factorH)
            
            x3 = iniX+self.length*((self.Cl[curPoint]/100)*0.5+(100-self.HCO3CO3[curPoint])/100*0.5)
            y3 = self.length*(self.SO4[curPoint]/100)*self.factorH

            x2 = iniXHalf +self.length*(-(100-self.NaK[curPoint])/100*0.5+(100-self.HCO3CO3[curPoint])/100*0.5)
            y2 = self.smallHeight+self.length*(+(100-self.NaK[curPoint])/100+(100-self.HCO3CO3[curPoint])/100)*self.factorH
            
            x = [x1, x2, x3]
            y = [y1, y2, y3]
            label = self.labels[curPoint]
            
            self.private_plot(x, y, label, curPoint)
    
    def updateTextsOnLayers(self, event):
        for label in self.rotated_labels:
            # slope_degrees is in data coordinates, the text() and annotate() functions need it in screen coordinates
            text = label["text"]
            p1, p2 = label["p1"], label["p2"]
    
            # get the line's data transform    
            sp1 = self.ax.transData.transform_point(p1)
            sp2 = self.ax.transData.transform_point(p2)    
            rise = (sp2[1] - sp1[1])
            run = (sp2[0] - sp1[0])    
            slope_degrees = math.degrees(math.atan(rise/run))
            text.set_rotation(slope_degrees)
            
def plotPiper1():

    plot = PiperPlot()    
    labels = ["well_1", "well_2", "well_3", "well_4"]    
    Ca = [20.0, 30.0, 50.0, 60.0]
    Mg = [30.0, 10.0, 20.0, 30.0]
    NaK = [50.0, 60.0, 30.0, 10.0]  
    HCO3CO3 = [5.0, 30.0, 85.0, 40.0]  
    SO4 = [10.0, 30.0, 5.0, 30.0]  
    Cl = [85.0, 40.0, 10.0, 30.0]
    
    values = {'Ca':Ca, 'Mg':Mg, 'NaK':NaK, 'HCO3CO3':HCO3CO3, 'SO4':SO4, 'Cl':Cl}      
    plot.setData(labels, values)
    plot.draw()     

if __name__ == '__main__':
    
    app = QtGui.QApplication(sys.argv)    
    plotPiper1()    
    sys.exit(app.exec_())