Source code for sharppy.viz.stpef

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 *

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

__all__ = ['backgroundSTPEF', 'plotSTPEF']

[docs]class backgroundSTPEF(QtWidgets.QFrame): ''' Draw the background frame and lines for the Theta-E plot frame ''' def __init__(self): super(backgroundSTPEF, 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;}") font_ratio = 0.0512 if self.physicalDpiX() > 75: fsize = round(font_ratio * self.size().height()) else: fsize = round(font_ratio * self.size().height() + 1) self.fsize = fsize self.plot_font = QtGui.QFont('Helvetica', fsize + 1) self.box_font = QtGui.QFont('Helvetica', fsize) self.plot_metrics = QtGui.QFontMetrics( self.plot_font ) self.box_metrics = QtGui.QFontMetrics(self.box_font) self.plot_height = self.plot_metrics.xHeight() + 5 self.box_height = self.box_metrics.xHeight() + 5 self.lpad = 0.; self.rpad = 0. self.tpad = 5+ 2*self.plot_height; self.bpad = self.plot_height + 5 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.probmax = 70.; self.probmin = 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 setBlackPen(self, qp): color = QtGui.QColor('#000000') color.setAlphaF(.5) pen = QtGui.QPen(color, 0, QtCore.Qt.SolidLine) brush = QtGui.QBrush(QtCore.Qt.SolidPattern) qp.setPen(pen) qp.setBrush(brush) return qp
[docs] def draw_frame(self, qp): ''' Draw the background frame. qp: QtGui.QPainter object ''' ## set a new pen to draw with EF1_color = "#006600" EF2_color = "#FFCC33" EF3_color = "#FF0000" EF4_color = "#FF00FF" pen = QtGui.QPen(self.fg_color, 2, QtCore.Qt.SolidLine) qp.setPen(pen) qp.setFont(self.plot_font) rect1 = QtCore.QRectF(1.5, 2, self.brx, self.plot_height) qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'Conditional Tornado Probs based on STPC') qp.setFont(QtGui.QFont('Helvetica', self.fsize-1)) color = QtGui.QColor(EF1_color) pen = QtGui.QPen(color, 2, QtCore.Qt.SolidLine) qp.setPen(pen) rect1 = QtCore.QRectF(self.stpc_to_pix(.2), 2 + self.plot_height, 10, self.plot_height) qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'EF1+') color = QtGui.QColor(EF2_color) pen = QtGui.QPen(color, 2, QtCore.Qt.SolidLine) qp.setPen(pen) rect1 = QtCore.QRectF(self.stpc_to_pix(1.1), 2 + self.plot_height, 10, self.plot_height) qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'EF2+') color = QtGui.QColor(EF3_color) pen = QtGui.QPen(color, 2, QtCore.Qt.SolidLine) qp.setPen(pen) rect1 = QtCore.QRectF(self.stpc_to_pix(3.1), 2 + self.plot_height, 10, self.plot_height) qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'EF3+') color = QtGui.QColor(EF4_color) pen = QtGui.QPen(color, 2, QtCore.Qt.SolidLine) qp.setPen(pen) rect1 = QtCore.QRectF(self.stpc_to_pix(6.1), 2 + self.plot_height, 10, self.plot_height) qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'EF4+') pen = QtGui.QPen(QtCore.Qt.blue, 1, QtCore.Qt.DashLine) qp.setPen(pen) ytick_fontsize = self.fsize y_ticks_font = QtGui.QFont('Helvetica', ytick_fontsize) qp.setFont(y_ticks_font) efstp_inset_data = inset_data.condSTPData() texts = efstp_inset_data['ytexts'] spacing = self.bry / 10. y_ticks = np.arange(self.tpad, self.bry+spacing, spacing) for i in range(len(y_ticks)): pen = QtGui.QPen(QtGui.QColor("#0080FF"), 1, QtCore.Qt.DashLine) qp.setPen(pen) try: qp.drawLine(self.tlx, self.prob_to_pix(int(texts[i])), self.brx, self.prob_to_pix(int(texts[i]))) except: continue color = QtGui.QColor('#000000') pen = QtGui.QPen(color, 1, QtCore.Qt.SolidLine) qp.setPen(pen) ypos = spacing*(i+1) - (spacing/4.) ypos = self.prob_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]) width = self.brx / 12 spacing = self.brx / 12 center = np.arange(spacing, self.brx, spacing) - width/2. texts = efstp_inset_data['xticks'] # Draw the x tick marks qp.setFont(QtGui.QFont('Helvetica', self.fsize - 2)) for i in range(np.asarray(texts).shape[0]): color = QtGui.QColor('#000000') color.setAlpha(0) pen = QtGui.QPen(color, 1, QtCore.Qt.SolidLine) rect = QtCore.QRectF(center[i], self.bry + self.bpad/2, width, 4) # 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]) # Draw the EF1+ stuff ef1 = efstp_inset_data['EF1+'] color = QtGui.QColor(EF1_color) pen = QtGui.QPen(color, 3, QtCore.Qt.SolidLine) qp.setPen(pen) for i in range(1, np.asarray(texts).shape[0], 1): qp.drawLine(center[i-1] + width/2, self.prob_to_pix(ef1[i-1]), center[i] + width/2, self.prob_to_pix(ef1[i])) # Draw the EF2+ stuff ef1 = efstp_inset_data['EF2+'] color = QtGui.QColor(EF2_color) pen = QtGui.QPen(color, 3, QtCore.Qt.SolidLine) qp.setPen(pen) for i in range(1, np.asarray(texts).shape[0], 1): qp.drawLine(center[i-1] + width/2, self.prob_to_pix(ef1[i-1]), center[i] + width/2, self.prob_to_pix(ef1[i])) # Draw the EF3+ stuff ef1 = efstp_inset_data['EF3+'] color = QtGui.QColor(EF3_color) pen = QtGui.QPen(color, 3, QtCore.Qt.SolidLine) qp.setPen(pen) for i in range(1, np.asarray(texts).shape[0], 1): qp.drawLine(center[i-1] + width/2, self.prob_to_pix(ef1[i-1]), center[i] + width/2, self.prob_to_pix(ef1[i])) # Draw the EF4+ stuff ef1 = efstp_inset_data['EF4+'] color = QtGui.QColor(EF4_color) pen = QtGui.QPen(color, 3, QtCore.Qt.SolidLine) qp.setPen(pen) for i in range(1, np.asarray(texts).shape[0], 1): qp.drawLine(center[i-1] + width/2, self.prob_to_pix(ef1[i-1]), center[i] + width/2, self.prob_to_pix(ef1[i]))
[docs] def prob_to_pix(self, prob): scl1 = self.probmax - self.probmin scl2 = self.probmin + prob return self.bry - (scl2 / scl1) * (self.bry - self.tpad)
[docs] def stpc_to_pix(self, stpc): spacing = self.brx / 12 center = np.arange(spacing, self.brx, spacing) if stpc == 0: i = 0 elif stpc >= 0.01 and stpc < .5: i = 1 elif stpc >= .5 and stpc < 1: i = 2 elif stpc >= 1 and stpc < 2: i = 3 elif stpc >= 2 and stpc < 3: i = 4 elif stpc >= 3 and stpc < 4: i = 5 elif stpc >= 4 and stpc < 6: i = 6 elif stpc >= 6 and stpc < 8: i = 7 elif stpc >= 8 and stpc < 10: i = 8 elif stpc >= 10 and stpc < 12: i = 9 else: i = 10 return center[i]
[docs]class plotSTPEF(backgroundSTPEF): ''' 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.use_left = False super(plotSTPEF, self).__init__() self.prof = None
[docs] def setProf(self, prof): self.prof = prof if self.use_left: self.stpc = prof.left_stp_cin else: self.stpc = prof.right_stp_cin 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']) if update_gui: if self.use_left: self.stpc = self.prof.left_stp_cin else: self.stpc = self.prof.right_stp_cin self.clearData() self.plotBackground() self.plotData() self.update()
[docs] def setDeviant(self, deviant): self.use_left = deviant == 'left' if self.use_left: self.stpc = self.prof.left_stp_cin else: self.stpc = self.prof.right_stp_cin self.clearData() self.plotBackground() self.plotData() self.update()
[docs] def resizeEvent(self, e): ''' Handles when the window is resized ''' super(plotSTPEF, self).resizeEvent(e) self.plotData()
[docs] def paintEvent(self, e): super(plotSTPEF, 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_stp(qp)
[docs] def draw_stp(self, qp): qp.begin(self.plotBitMap) qp.setRenderHint(qp.Antialiasing) qp.setRenderHint(qp.TextAntialiasing) stpc_pix = self.stpc_to_pix(self.stpc) pen = QtGui.QPen(self.fg_color, 1.5, QtCore.Qt.DotLine) qp.setPen(pen) qp.drawLine(stpc_pix, self.prob_to_pix(0), stpc_pix, self.prob_to_pix(70)) qp.end()
if __name__ == '__main__': app_frame = QtGui.QApplication([]) tester = plotSTPEF() tester.show() app_frame.exec_()