Skip to content

Angled/Skewed Axis #454

Description

@keltonhalbert

Hello,

I'd like to inquire about and offer to help add a feature I'd like to be able to use but I'm not quite sure where to start with implementing it. There's a scientific chart I'd like to make called a Skew-T Log-P diagram. The Y axis (Pressure as a vertical coordinate) is in logarithmic space, which thankfully core-plot already does! The strange part is that the X-axis is skewed (Temperature) anywhere from 33-45 degrees to the right of the vertical axis. I noticed that there is a not-yet implemented ScaleType identifier called 'angular', which sounds like it would be a good direction for being able to implement such a transformation. Here's an example plot below. The solid red line highlighted as the freezing level is an example of how a constant X axis value is represented by a slanted line.

image

The Charts library for iOS has the ability to apply a matrix transform in which the underlying data can be skewed, but there's nothing for the axis lines. Awkwardly, Charts also doesn't support logarithmic data spaces easily. I would also prefer to use core-plot since it leverages the GPU more than Charts. I'd also prefer to be able to keep things in data-space coordinates and implement this at a lower level.

I've implemented this a little more directly before using Qt Widgets using the following functions to transform from data space to pixel space. I understand that implementing this would be required at a lower level than what's done in Qt here, but if I can be directed to a good starting place I think I could figure out the rest and make a pull request.

Any suggestions on where to start?

def initUI(self):
        ## These are some padding variables for axis drawing, and data-space limits on the graph
        self.lpad = 30; self.rpad = 65
        self.tpad = 20; self.bpad = 20
        self.tlx = self.rpad; self.tly = self.tpad
        self.wid = self.size().width() - self.rpad
        self.hgt = self.size().height() - self.bpad
        self.brx = self.wid ; self.bry = self.hgt
        self.pmax = 1050.; self.pmin = 100.
        self.barbx = self.brx + self.rpad / 2
        self.log_pmax = np.log(self.pmax); self.log_pmin = np.log(self.pmin)
        self.bltmpc = -50; self.brtmpc = 50; self.dt = 10
        self.xskew = 100 / 3.
        self.xrange = self.brtmpc - self.bltmpc
        self.yrange = np.tan(np.deg2rad(self.xskew)) * self.xrange
        self.clip = QRect(QPoint(self.lpad, self.tly), QPoint(self.brx + self.rpad, self.bry))
        self.originx = 0. # self.size().width() / 2
        self.originy = 0. # self.size().height() / 2
        self.scale = 1.
    def pres_to_pix(self, p):
        scl1 = self.log_pmax - self.log_pmin
        scl2 = self.log_pmax - np.log(p)
        return self.bry - (scl2 / scl1) * (self.bry - self.tpad)

    def tmpc_to_pix(self, t, p):
         scl1 = self.brtmpc - (((self.bry - self.pres_to_pix(p)) /
                              (self.bry - self.tpad)) * self.yrange)
        return self.brx - (((scl1 - t) / self.xrange) * (self.brx - self.lpad))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions