0

I am trying to generate a pcolormesh where the color gradient will vary depending upon a non-linear periodic function such as abs of cos. A custom normalization should suffice. So far I tried the code below:

class XNormalize(mcolors.Normalize):
    def __call__(self, value, clip=None):
        return np.ma.masked_array(np.abs(np.cos(value)))

I am not sure apply self.vmin, self.vmax mapping in this case since the cos can virtually take any input.

The code to generate output:

inner_azimuths = np.arange(0, 361, 1)
inner_zeniths = np.arange(50, 55, 1)
inner_values = inner_azimuths * np.ones((5, 361))
fig = plt.figure(tight_layout=True)
ax = fig.add_subplot(111, polar=True)
ax.pcolormesh((inner_azimuths)*np.pi/180.0, inner_zeniths, inner_values, cmap='jet_r', zorder=2, antialiased=True, norm=XNormalize(vmin=0, vmax=2*np.pi))

The output currently looks like the follows:

Current plot

I also tried the following function:

def distortColorMap(cm,inv = lambda x:x):
    """Inspired from 'make_colormap' in Serenity's answer.

    Inputs : a pre-existing colormap cm, 
            the distorsion function inv

    Output : the distorted colormap"""

    def f(color,inv):
        """In the sequence definition, modifies the position of stops tup[0] according the transformation function.

        Returns the distorted sequence."""
        return map(lambda tup:(inv(tup[0]),tup[1],tup[2]),color)

    # Extract sequences from cm, apply inv
    C = cm.__dict__['_segmentdata']
    cdict = {'red': f(C['red']  ,inv), 'green': f(C['green'],inv), 'blue': f(C['blue'] ,inv)}

    name = 'new_'+cm.__dict__['name']
    return colors.LinearSegmentedColormap(name, cdict)

Bit it did not work as well.

Sources: (a), (b)

tachyon
  • 471
  • 3
  • 14
  • I don't think it's clear what exactly does not work here. To me the code seems fine. In how far is the output not expected? – ImportanceOfBeingErnest Mar 03 '19 at 09:57
  • I want a smooth gradient radially between two angles, not a repeating fringe. For example, when I use default linear normalization the output is like: ![Smooth Plot](https://i.imgur.com/0sWDrQm.png) – tachyon Mar 03 '19 at 10:53
  • Isn't that a question of input data? Currently your values range from 0 to 360. That would correspont to roughly 60 periods of the cosine, or 120 periods of the absolute cosine. That's close to what you see in the plot. – ImportanceOfBeingErnest Mar 03 '19 at 11:33
  • Inner_values needs to be in radians (or you need to change your Norm to work with radians) – Jody Klymak Mar 04 '19 at 15:50
  • I knew that the `values` have to be passed as radians. So, I converted the values to radian manually by doing `(inner_azimuths)*np.pi/180.0`, somehow it did not work. Now, It works when I pass `np.deg2rad(inner_azimuths)` instead. Finally solved. Thanks. – tachyon Mar 06 '19 at 07:33

0 Answers0