Source code for sharppy.viz.ship

import numpy as np
import os
from qtpy import QtGui, QtCore, QtWidgets
import sharppy.sharptab as tab
import sharppy.databases.inset_data as inset_data
from sharppy.sharptab.constants import *
import platform 

## routine written by Kelton Halbert and Greg Blumberg
## keltonhalbert@ou.edu and wblumberg@ou.edu

__all__ = ['backgroundSHIP', 'plotSHIP']

[docs]class backgroundSHIP(QtWidgets.QFrame): ''' Draw the background frame and lines for the Theta-E plot frame ''' def __init__(self): super(backgroundSHIP, self).__init__() self.initUI()
[docs] def initUI(self): ## window configuration settings, ## sich as padding, width, height, and ## min/max plot axes self.setStyleSheet("QFrame {" " background-color: rgb(0, 0, 0);" " border-width: 1px;" " border-style: solid;" " border-color: #3399CC;}") self.textpad = 5 self.font_ratio = 0.0512 fsize1 = round(self.size().height() * self.font_ratio) + 2 fsize2 = round(self.size().height() * self.font_ratio) self.plot_font = QtGui.QFont('Helvetica', fsize1 ) self.box_font = QtGui.QFont('Helvetica', fsize2) self.plot_metrics = QtGui.QFontMetrics( self.plot_font ) self.box_metrics = QtGui.QFontMetrics(self.box_font) if platform.system() == "Windows": fsize1 -= self.plot_metrics.descent() fsize2 -= self.box_metrics.descent() self.plot_font = QtGui.QFont('Helvetica', fsize1 ) self.box_font = QtGui.QFont('Helvetica', fsize2) self.plot_metrics = QtGui.QFontMetrics( self.plot_font ) self.box_metrics = QtGui.QFontMetrics(self.box_font) self.plot_height = self.plot_metrics.xHeight()# + self.textpad self.box_height = self.box_metrics.xHeight() + self.textpad self.tpad = self.plot_height + 15; self.bpad = self.plot_height + 2 self.lpad = 0.; self.rpad = 0. self.wid = self.size().width() - self.rpad self.hgt = self.size().height() - self.bpad self.tlx = self.rpad; self.tly = self.tpad; self.brx = self.wid; self.bry = self.hgt - self.bpad#+ round(self.font_ratio * self.hgt) self.shipmax = 5.; self.shipmin = 0. self.plotBitMap = QtGui.QPixmap(self.width()-2, self.height()-2) self.plotBitMap.fill(self.bg_color) self.plotBackground()
[docs] def resizeEvent(self, e): ''' Handles the event the window is resized ''' self.initUI()
[docs] def plotBackground(self): ''' Handles painting the frame. ''' ## initialize a painter object and draw the frame qp = QtGui.QPainter() qp.begin(self.plotBitMap) qp.setRenderHint(qp.Antialiasing) qp.setRenderHint(qp.TextAntialiasing) self.draw_frame(qp) qp.end()
[docs] def draw_frame(self, qp): ''' Draw the background frame. qp: QtGui.QPainter object ''' ## set a new pen to draw with pen = QtGui.QPen(self.fg_color, 2, QtCore.Qt.SolidLine) qp.setPen(pen) qp.setFont(self.plot_font) rect1 = QtCore.QRectF(1.5,6, self.brx, self.plot_height) qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'Significant Hail Param (SHIP)') pen = QtGui.QPen(QtCore.Qt.blue, 1, QtCore.Qt.DashLine) qp.setPen(pen) spacing = self.bry / 6. ytick_fontsize = round(self.font_ratio * self.hgt) y_ticks_font = QtGui.QFont('Helvetica', ytick_fontsize) qp.setFont(y_ticks_font) ship_inset_data = inset_data.shipData() texts = ship_inset_data['ship_ytexts'] for i in range(len(texts)): pen = QtGui.QPen(self.line_color, 1, QtCore.Qt.DashLine) qp.setPen(pen) try: qp.drawLine(self.tlx, self.ship_to_pix(int(texts[i])), self.brx, self.ship_to_pix(int(texts[i]))) except: continue color = QtGui.QColor(self.bg_color) pen = QtGui.QPen(color, 1, QtCore.Qt.SolidLine) qp.setPen(pen) ypos = spacing*(i+1) - (spacing/4.) ypos = self.ship_to_pix(int(texts[i])) - ytick_fontsize/2 rect = QtCore.QRect(self.tlx, ypos, 20, ytick_fontsize) pen = QtGui.QPen(self.fg_color, 1, QtCore.Qt.SolidLine) qp.setPen(pen) qp.drawText(rect, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, texts[i]) ef = ship_inset_data['ship_dist'] width = self.brx / 3.7 spacing = self.brx / 3 center = np.arange(spacing, self.brx, spacing) texts = ship_inset_data['ship_xtexts'] ef = self.ship_to_pix(ef) qp.setFont(QtGui.QFont('Helvetica', round(self.font_ratio * self.hgt))) for i in range(ef.shape[0]): # Set green pen to draw box and whisker plots pen = QtGui.QPen(self.box_color, 2, QtCore.Qt.SolidLine) qp.setPen(pen) # Draw lower whisker qp.drawLine(center[i], ef[i,0], center[i], ef[i,1]) # Draw box qp.drawLine(center[i] - width/2., ef[i,3], center[i] + width/2., ef[i,3]) qp.drawLine(center[i] - width/2., ef[i,1], center[i] + width/2., ef[i,1]) qp.drawLine(center[i] - width/2., ef[i,1], center[i] - width/2., ef[i,3]) qp.drawLine(center[i] + width/2., ef[i,1], center[i] + width/2., ef[i,3]) # Draw median #qp.drawLine(center[i] - width/2., ef[i,2], center[i] + width/2., ef[i,2]) # Draw upper whisker qp.drawLine(center[i], ef[i,3], center[i], ef[i,4]) # Set black transparent pen to draw a rectangle color = QtGui.QColor(self.bg_color) color.setAlpha(0) pen = QtGui.QPen(color, 1, QtCore.Qt.SolidLine) rect = QtCore.QRectF(center[i] - width/2., self.bry + self.bpad/2, width, self.bpad) # Change to a white pen to draw the text below the box and whisker plot pen = QtGui.QPen(self.fg_color, 1, QtCore.Qt.SolidLine) qp.setPen(pen) qp.drawText(rect, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, texts[i])
[docs] def ship_to_pix(self, ship): scl1 = self.shipmax - self.shipmin scl2 = self.shipmin + ship return self.bry - (scl2 / scl1) * (self.bry - self.tpad)
[docs]class plotSHIP(backgroundSHIP): ''' Plot the data on the frame. Inherits the background class that plots the frame. ''' def __init__(self): self.bg_color = QtGui.QColor('#000000') self.fg_color = QtGui.QColor('#ffffff') self.box_color = QtGui.QColor('#00ff00') self.line_color = QtGui.QColor('#0080ff') self.alert_colors = [ QtGui.QColor('#775000'), QtGui.QColor('#996600'), QtGui.QColor('#ffffff'), QtGui.QColor('#ffff00'), QtGui.QColor('#ff0000'), QtGui.QColor('#e700df'), ] super(plotSHIP, self).__init__() self.prof = None
[docs] def setProf(self, prof): self.prof = prof self.ship = prof.ship self.clearData() self.plotBackground() self.plotData() self.update()
[docs] def setPreferences(self, update_gui=True, **prefs): self.bg_color = QtGui.QColor(prefs['bg_color']) self.fg_color = QtGui.QColor(prefs['fg_color']) self.box_color = QtGui.QColor(prefs['stp_box_color']) self.line_color = QtGui.QColor(prefs['stp_line_color']) self.alert_colors = [ QtGui.QColor(prefs['alert_l1_color']), QtGui.QColor(prefs['alert_l2_color']), QtGui.QColor(prefs['alert_l3_color']), QtGui.QColor(prefs['alert_l4_color']), QtGui.QColor(prefs['alert_l5_color']), QtGui.QColor(prefs['alert_l6_color']), ] if update_gui: self.clearData() self.plotBackground() self.plotData() self.update()
[docs] def resizeEvent(self, e): ''' Handles when the window is resized ''' super(plotSHIP, self).resizeEvent(e) self.plotData()
[docs] def paintEvent(self, e): super(plotSHIP, self).paintEvent(e) qp = QtGui.QPainter() qp.begin(self) qp.drawPixmap(1, 1, self.plotBitMap) qp.end()
[docs] def clearData(self): ''' Handles the clearing of the pixmap in the frame. ''' self.plotBitMap = QtGui.QPixmap(self.width(), self.height()) self.plotBitMap.fill(self.bg_color)
[docs] def plotData(self): ''' Handles painting on the frame ''' if self.prof is None: return ## this function handles painting the plot ## create a new painter obkect qp = QtGui.QPainter() self.draw_ship(qp)
[docs] def draw_ship(self, qp): if not tab.utils.QC(self.ship): return qp.begin(self.plotBitMap) qp.setRenderHint(qp.Antialiasing) qp.setRenderHint(qp.TextAntialiasing) if self.ship < self.shipmin: self.ship = self.shipmin elif self.ship > self.shipmax: self.ship = self.shipmax color = self.ship_color(self.ship) ef = self.ship_to_pix(self.ship) pen = QtGui.QPen(color, 1.5, QtCore.Qt.SolidLine) qp.setPen(pen) qp.drawLine(0, ef, self.wid, ef) qp.end()
[docs] def ship_color(self, ship): color_list = self.alert_colors if float(ship) >= 5: color = color_list[5] elif float(ship) >= 2: color = color_list[4] elif float(ship) >= 1: color = color_list[3] elif float(ship) >= .5: color = color_list[2] else: color = color_list[0] return color
if __name__ == '__main__': app_frame = QtGui.QApplication([]) tester = plotSHIP() tester.show() app_frame.exec_()