Non linear colormap/colorbar

1,840 views
Skip to first unread message

Martin Rugna

unread,
Oct 26, 2015, 4:32:02 PM10/26/15
to Py-ART Users
Hello to everyone, 

I'm trying to plot RhoHV using plot_ppi_map but I'm not getting PyART to use a custom non linear colormap and a colorbar. 

This is, I want to have a colorbar with equispaced tick label but not equispaced values [1] so it has more color range on the upper side. I also want the colorbar to be listed, not the default gradient. AND at the same time I want the custom colormap (an RGB list) to actually show this.

These links I found work partially for contour [2] and scatter [3] plots but I want to make the colormap an input of plot_ppi_map. I used virtually everything but PyART refuses to work with any function. Any ideas?


[1] v=[0.4 0.5 0.6 0.7 0.8 0.85 0.9 0.93 0.95 0.96 0.97 0.98 0.99 0.994 0.998 1]


Jonathan Helmus

unread,
Oct 27, 2015, 4:51:15 PM10/27/15
to pyart...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "Py-ART Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyart-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin,

    From some investigation matplotlib does not appear to be able to show a non-linear colormap with a non-linear colorbar natively.  Plotting a pcolormesh using a non-linear colormap is typically not too much work but is a bit difficult since Py-ART's Radardisplay class does not pass the norm parameter to the pcolormesh calls.   Rather the colormap must be made non-linear.  If you plot the colorbar as if it corresponds to categorical data then the results are similar to a non-linear colorbar but are segmented.

Below is a script that is my best attempt at a non-linear colormap and colorbar using one of the Py-ART examples:

import matplotlib.pyplot as plt
import matplotlib.colors as colors
import pyart
import numpy as np

# create a non-linear colormap
cbar_limits = [0.0, 0.4, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9,
     0.93, 0.95, 0.96, 0.97, 0.98, 0.99, 0.994, 0.998, 1]
nlimits = len(cbar_limits)

ref_cmap = plt.get_cmap('jet', nlimits)
segmentdata = colors.LinearSegmentedColormap.from_list(
    'test', ref_cmap(np.linspace(0, 1, nlimits)))._segmentdata

cdict = {'red': [], 'green': [], 'blue': []}
for i, j in enumerate(cbar_limits):
    mn, mx = segmentdata['red'][i][1:]
    red_tuple = (j, mn, mx)
    cdict['red'].append(red_tuple)

    mn, mx = segmentdata['green'][i][1:]
    green_tuple = (j, mn, mx)
    cdict['green'].append(green_tuple)

    mn, mx = segmentdata['blue'][i][1:]
    blue_tuple = (j, mn, mx)
    cdict['blue'].append(blue_tuple)
nonlin_cmap = colors.LinearSegmentedColormap('nonlinear', cdict)

# plot the data
filename = '110635.mdv'
radar = pyart.io.read_mdv(filename)
display = pyart.graph.RadarDisplay(radar)
fig = plt.figure()
ax = fig.add_subplot(111)
display.plot('normalized_coherent_power', 0, vmin=0, vmax=1.0,
             colorbar_flag=False, title_flag=False,
             axislabels_flag=False, cmap=nonlin_cmap)

# plot the colorbar as if it was categorical to trick matplotlib to use uniform
# spacing between colors
fig.colorbar(
    display.plots[-1], orientation='vertical', spacing='uniform',
    boundaries=cbar_limits+[1.1], values=cbar_limits, ticks=cbar_limits)
display.set_limits(ylim=[-120, 120], xlim=[-120, 120])
plt.show()

Cheers,

    - Jonathan Helmus

Yogesh Kolte

unread,
Oct 30, 2015, 10:39:18 AM10/30/15
to Py-ART Users
Hello Sir,

 I am trying to compare reflectivity of X and Ka band radar data which are co-located. but when i plotting Ka-band data  from .NC file the plot is shifted by some degree from north so  i used 'radar.azimuth['data'] = (radar.azimuth['data'] + 10.)' to rotate PPI plot.

I want to plot slanted range versus DBz at given angle for both radar so how can i do?
How can i  divide color bar  for DBz in different range and color .

On 28 October 2015 at 02:19, Jonathan Helmus <jjhe...@gmail.com> wrote:
Boxbe This message is eligible for Automatic Cleanup! (jjhe...@gmail.com) Add cleanup rule | More info

On 10/26/2015 03:32 PM, Martin Rugna wrote:

Jonathan Helmus

unread,
Oct 30, 2015, 11:54:07 AM10/30/15
to pyart...@googlegroups.com
On 10/30/2015 09:39 AM, Yogesh Kolte wrote:
Hello Sir,

 I am trying to compare reflectivity of X and Ka band radar data which are co-located. but when i plotting Ka-band data  from .NC file the plot is shifted by some degree from north so  i used 'radar.azimuth['data'] = (radar.azimuth['data'] + 10.)' to rotate PPI plot.


This has the possibility of generate azimuthal angles greater than 360 degress, adding modules to the calculation will prevent this:

radar.azimuth['data'][:] = (radar.azimuth['data'] + 10) % 360.


I want to plot slanted range versus DBz at given angle for both radar so how can i do?
How can i  divide color bar  for DBz in different range and color .

I'm not sure what type of plot you are describing, can you provide some additional details?

    - Jonathan Helmus

Martin Rugna

unread,
Nov 9, 2015, 7:22:30 AM11/9/15
to Py-ART Users
Jonathan, sorry for the delay and thanks for the answer!

I post here what I got after applying the code you wrote and using a custom normalized RGB list, it's not perfect but it's light years ahead from what I had. The colorbar has some issue at the top doubling the last segment but again, I can live with that for now.

Chou Tat Hoi

unread,
Dec 18, 2015, 2:47:13 AM12/18/15
to Py-ART Users
Dear Jonathan,

I am trying to plot reflectivity and other product with non linear color bar.  But I was fail with below code. Could you tell me the mistakes?   And I also want to modifily it to a non rainbow like color bar as below pic. Please kindly teach me or give some references to me about that? Thank you for your assistance.   


import matplotlib.pyplot as plt
import matplotlib.colors as colors
import pyart
import numpy as np
 # create a non-linear colormap
cbar_limits = [2, 7, 12, 18, 21, 23, 28, 34,
      37, 39, 44, 50, 53, 55, 60, 66, 72]
nlimits = len(cbar_limits)
ref_cmap = plt.get_cmap('jet', nlimits)
segmentdata = colors.LinearSegmentedColormap.from_list(
     'test', ref_cmap(np.linspace(7, 72, nlimits)))._segmentdata

cdict = {'red': [], 'green': [], 'blue': []}
for i, j in enumerate(cbar_limits):
    mn, mx = segmentdata['red'][i][1:]
    red_tuple = (j, mn, mx)
    cdict['red'].append(red_tuple)
    mn, mx = segmentdata['green'][i][1:]
    green_tuple = (j, mn, mx)
    cdict['green'].append(green_tuple)
    mn, mx = segmentdata['blue'][i][1:]
    blue_tuple = (j, mn, mx)
    cdict['blue'].append(blue_tuple)
nonlin_cmap = colors.LinearSegmentedColormap('nonlinear', cdict)
# plot the data
filename = 'TCR151122190057.RAW1JSL'
radar = pyart.io.read(filename)

display = pyart.graph.RadarDisplay(radar)
fig = plt.figure()
ax = fig.add_subplot(111)
display.plot('reflectivity', 1, vmin=2, vmax=72,
             colorbar_flag=False, title_flag=False,
             axislabels_flag=False, cmap=nonlin_cmap)
# plot the colorbar as if it was categorical to trick matplotlib to use uniform
# spacing between colors
fig.colorbar(
    display.plots[-1], orientation='vertical', spacing='uniform',
    boundaries=cbar_limits+[1.1], values=cbar_limits, ticks=cbar_limits)
display.set_limits(ylim=[-260,260 ], xlim=[-260, 260])
plt.show()

Jonathan Helmus於 2015年10月28日星期三 UTC+8上午4時51分15秒寫道:
Auto Generated Inline Image 1

Jonathan Helmus

unread,
Jan 4, 2016, 3:06:19 PM1/4/16
to pyart...@googlegroups.com
Chou,

    You seem to want to plot reflectivity using a discrete interval colormap, unfortunately making and using discrete intervals based colormaps in Py-ART is not possible with the current Display classes as the norm parameter is not exposed in the call to pcolormesh.  I am planning on refactoring the Display classes this month and will add an option to provide method for specifying the norm parameter which will make non-linear and discrete colormaps possible.

     For the non rainbow like colormap, try using pyart.graph.cm.NWSRef, which has a similar color scheme to the graphic you linked. 

Cheers,

     - Jonathan Helmus

Chou Tat Hoi

unread,
Jan 4, 2016, 8:38:23 PM1/4/16
to Py-ART Users
Dear Jonathan,

We have just learn how to create a cmap class, thank you for your assist.

Jonathan Helmus於 2016年1月5日星期二 UTC+8上午4時06分19秒寫道:

Michael S

unread,
May 10, 2016, 2:15:43 PM5/10/16
to Py-ART Users
Hi Jonathan--

Were you able to re-factor the Display classes to specify the norm parameter?

Also, is it possible to have the colorbar be exactly the same colors for two different displays. E.g. if I want to look at the left-most and right-most figures found at https://arm-doe.github.io/pyart/dev/auto_examples/correct/plot_attenuation.html#example-correct-plot-attenuation-py and have them be on the same scale with the same colors.

Cheers,
Michael

Jonathan Helmus

unread,
May 10, 2016, 2:36:58 PM5/10/16
to pyart...@googlegroups.com
Michael,

    Yes, the Display class now allows users to specify the norm parameter.  You will need the latest release version of Py-ART (1.6) or the development version to use this feature.  You can fine a simple example of the use of this parameter in a comment [1] in issue #390.  The matplotlib documentation of Colormap normalization [2] may be of help also.

If anyone is interested in contributing a more complete example of how to use this would be a welcome addition to Py-ART examples collection.

If you specify the same vmin, vmax and cmap parameters when creating two plots the exact same scale and colors should be used for plotting the data.  If these are not explicitly specified in the method call default are determined from the name of the field which may be different depending on the field being plotted.

For example in the example you linked to, the plotting section should be changed to:

# create the plot
fig = plt.figure(figsize=(15, 5))
ax1 = fig.add_subplot(131)
display = pyart.graph.RadarDisplay(radar)
display.plot('reflectivity_horizontal', 0, ax=ax1,
             vmin=0, vmax=60., cmap='pyart_NWSRef',
             colorbar_label='', title='Raw Reflectivity')

ax2 = fig.add_subplot(132)
display.plot('specific_attenuation', 0, vmin=0, vmax=1.0,
             colorbar_label='', ax=ax2, title='Specific Attenuation')

ax3 = fig.add_subplot(133)
display = pyart.graph.RadarDisplay(radar)
display.plot('corrected_reflectivity_horizontal', 0,
             vmin=0, vmax=60., cmap='pyart_NWSRef',
             colorbar_label='', ax=ax3, title='Corrected Reflectivity')

plt.suptitle('Attenuation correction using Py-ART', fontsize=16)

plt.show()


Cheers,

    - Jonathan Helmus

dmc...@uah.edu

unread,
Sep 21, 2016, 6:07:02 PM9/21/16
to Py-ART Users
Hello Martin,

Would it be possible to post your code creating the rhohv cmap with the values displayed in the image below? Thanks!

Dustin

Martin Rugna

unread,
Sep 22, 2016, 10:08:17 AM9/22/16
to Py-ART Users
Dustin, the colors and values I used are

escala=[
    (1,1,1),
    (0.7969,0.9961,0.9961),
    (0.0156,0.9102,0.9023),
    (0.0039,0.6211,0.9531),
    (0.0117,0,0.9531),
    (0.0078,0.9883,0.0078),
    (0.0039,0.7695,0.0039),
    (0,0.5547,0),
    (0.9883,0.9688,0.0078),
    (0.8945,0.7344,0),
    (0.9883,0.582,0),
    (0.9883,0,0),
    (0.8281,0,0),
    (0.7344,0,0),
    (0.9688,0,0.9883),
    (0.5938,0.3281,0.7734),
    (0.5742,0,0.9336)
    ]

cbar_limits = [0.0, 0.4, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9,
     0.93, 0.95, 0.96, 0.97, 0.98, 0.99, 0.994, 0.998, 1]
nlimits = len(cbar_limits)

ref_cmap = colors.LinearSegmentedColormap.from_list('test', escala)
segmentdata = colors.LinearSegmentedColormap.from_list(
    'test', ref_cmap(np.linspace(0, 1, nlimits)))._segmentdata

From here it's pretty much the same code Jonathan posted before.

-Martin
Reply all
Reply to author
Forward
0 new messages