Discussion:
[Matplotlib-users] Confused about rgb_to_hsv and hsv_to_rgb
Matteo Niccoli
2015-05-21 15:50:54 UTC
Permalink
I posted a question on stackoverflow about creating with making my own
shading effect (I want to use horizontal gradient for the shading).
http://stackoverflow.com/questions/30310002/issue-creating-map-shading-in-matplotlib-imshow-by-setting-opacity-to-data-gradi


Unfortunately I cannot share the data because I am using it for a
manuscripts, but my notebook with full code listing and plots, here:
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/surface_shading.ipynb/%3Fdl%3D0

The shading using gradient is implemented in two ways as suggested in the
answer. What I do not understand is why the last plot comes out with a
rainbow-like colors, when I did specify cubehelix as colormap.

hsv = cl.rgb_to_hsv(img_array[:, :, :3])
hsv[:, :, 2] = tdx_n
rgb = cl.hsv_to_rgb(hsv)
plt.imshow(rgb[4:-3,4:-3], cmap='cubehelix')
plt.show()


Am I doing something wrong or is this unexpected behavior; is there a
workaround?

Thanks
Matteo
Eric Firing
2015-05-21 20:10:09 UTC
Permalink
Post by Matteo Niccoli
I posted a question on stackoverflow about creating with making my own
shading effect (I want to use horizontal gradient for the shading).
http://stackoverflow.com/questions/30310002/issue-creating-map-shading-in-matplotlib-imshow-by-setting-opacity-to-data-gradi
Unfortunately I cannot share the data because I am using it for a
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/surface_shading.ipynb/%3Fdl%3D0
The shading using gradient is implemented in two ways as suggested in the
answer. What I do not understand is why the last plot comes out with a
rainbow-like colors, when I did specify cubehelix as colormap.
hsv = cl.rgb_to_hsv(img_array[:, :, :3])
hsv[:, :, 2] = tdx_n
rgb = cl.hsv_to_rgb(hsv)
plt.imshow(rgb[4:-3,4:-3], cmap='cubehelix')
plt.show()
Am I doing something wrong or is this unexpected behavior; is there a
workaround?
Colormapping occurs only when you give imshow a 2-D array of numbers to
be mapped; when you feed it a 3-D array of RGB values, it simply shows
those colors. For colormapping to occur, it must be done on a 2-D array
as a step leading up to the generation of your img_array.

Eric
Post by Matteo Niccoli
Thanks
Matteo
Matteo Niccoli
2015-05-21 21:28:21 UTC
Permalink
OK, I understand.


Could you suggest a way to reduce that 3D array to a 2D array and plot it
with a specific colormap, while preserving the shading?

I did something similar in Matlab

https://mycarta.wordpress.com/2012/04/05/visualization-tips-for-geoscientists-matlab-part-ii/

But it took using some custom functions and a ton of asking and tinkering,
and I'm not quite at that level with matplotlib, so any suggestion would
be appreciated

Thanks,
Matteo
Post by Eric Firing
Colormapping occurs only when you give imshow a 2-D array of numbers to
be mapped; when you feed it a 3-D array of RGB values, it simply shows
those colors. For colormapping to occur, it must be done on a 2-D array
as a step leading up to the generation of your img_array.
Eric
Post by Matteo Niccoli
I posted a question on stackoverflow about creating with making my own
shading effect (I want to use horizontal gradient for the shading).
http://stackoverflow.com/questions/30310002/issue-creating-map-shading-
in-matplotlib-imshow-by-setting-opacity-to-data-gradi
Unfortunately I cannot share the data because I am using it for a
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/surfa
ce_shading.ipynb/%3Fdl%3D0
The shading using gradient is implemented in two ways as suggested in
the answer. What I do not understand is why the last plot comes out with
a rainbow-like colors, when I did specify cubehelix as colormap.
hsv = cl.rgb_to_hsv(img_array[:, :, :3]) hsv[:, :, 2] = tdx_n
rgb = cl.hsv_to_rgb(hsv) plt.imshow(rgb[4:-3,4:-3], cmap='cubehelix')
plt.show()
Am I doing something wrong or is this unexpected behavior; is there a
workaround?
Thanks
Matteo
-------------------------------------------------------------------------
-----
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Eric Firing
2015-05-21 23:02:44 UTC
Permalink
Post by Matteo Niccoli
OK, I understand.
Could you suggest a way to reduce that 3D array to a 2D array and plot it
with a specific colormap, while preserving the shading?
It looks like you will get what you want by following the titusjan's
advice in his reply. If you are not seeing a shaded version of
cubehelix, then the only thing I can imagine is that you inadvertently
omitted the second line in his example:

img_array = plt.get_cmap('cubehelix')(data_n)

This is doing the colormapping at the start, generating the 3D array
that you modify to apply your shading algorithm.

Eric
Joe Kington
2015-05-22 12:28:31 UTC
Permalink
I think you're asking how to blend a custom intensity image with an rgb
image. (I'm traveling and just have my phone, so you'll have to excuse my
lack of examples.)

There are several ways to do this. Basically, it's analogous to "blend
modes" in Photoshop etc.

Have a look at the matplotlib.colors.LightSource.blend_overlay and
blend_soft_light functions in the current github head. (And also
http://matplotlib.org/devdocs/examples/specialty_plots/topographic_hillshading.html
)

If you're working with 1.4.x, though, you won't have those functions.

However, the math is very simple. Have a look at the code in those
functions in the github head. It's basically a one liner.

You'll need both the 4-band rgba image and the 1 band intensity/hillshade
image to be floating point arrays scaled from 0-1. However, this is the
default in matplotlib.

How that helps a bit, and sorry again for the lack of examples!
Joe
OK, I understand.


Could you suggest a way to reduce that 3D array to a 2D array and plot it
with a specific colormap, while preserving the shading?

I did something similar in Matlab

https://mycarta.wordpress.com/2012/04/05/visualization-tips-for-geoscientists-matlab-part-ii/

But it took using some custom functions and a ton of asking and tinkering,
and I'm not quite at that level with matplotlib, so any suggestion would
be appreciated

Thanks,
Matteo
Post by Eric Firing
Colormapping occurs only when you give imshow a 2-D array of numbers to
be mapped; when you feed it a 3-D array of RGB values, it simply shows
those colors. For colormapping to occur, it must be done on a 2-D array
as a step leading up to the generation of your img_array.
Eric
Post by Matteo Niccoli
I posted a question on stackoverflow about creating with making my own
shading effect (I want to use horizontal gradient for the shading).
http://stackoverflow.com/questions/30310002/issue-creating-map-shading-
in-matplotlib-imshow-by-setting-opacity-to-data-gradi
Unfortunately I cannot share the data because I am using it for a
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/surfa
ce_shading.ipynb/%3Fdl%3D0
The shading using gradient is implemented in two ways as suggested in
the answer. What I do not understand is why the last plot comes out with
a rainbow-like colors, when I did specify cubehelix as colormap.
hsv = cl.rgb_to_hsv(img_array[:, :, :3]) hsv[:, :, 2] = tdx_n
rgb = cl.hsv_to_rgb(hsv) plt.imshow(rgb[4:-3,4:-3], cmap='cubehelix')
plt.show()
Am I doing something wrong or is this unexpected behavior; is there a
workaround?
Thanks
Matteo
-------------------------------------------------------------------------
-----
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Matteo Niccoli
2015-05-22 19:33:35 UTC
Permalink
Joe, Eric

Thanks to both for your further comments.
I made a new notebook, this time using open source data so it can be
downloaded and followed step by step.
The html version in nbviewer is here:
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/surface_shading.ipynb/%3Fdl%3D0
Data is here:
https://www.dropbox.com/s/p87bojlnmad9p9j/Penobscot_HorB.txt?dl=0
The first method suggested by titusjan on stackoverflow is essentially the
same as the matplotlib.colors blend_soft_ligh suggested by Joe as it uses
the pegtop algorithm. It works nicely with the data.

The second method suggested by titusjan replaces value in hsv space with
intensity as suggested. Eric you will notce I did include the line
img_array = plt.get_cmap('cubehelix')(data_n) and yet the colormapping is
not working.

I am very keen to sort out if this is a bug in the software or a problem
in my code, and if there is a way to make it work. The reason is that this
method would allow blending three pieces of information, to create a
figure like the top one in here:
https://books.google.ca/books?id=dP2iACuzq34C&q=figure+20#v=snippet&q=a%20time%20slice%20through%20a%20survey%20acquired%20over%20the%20Central%20Basin%20Platform%2C%20Texas%2C%20U.S.A.%2C%20using%20a%203D&f=false
Any further insight would be really appreciated.

Matteo
Post by Joe Kington
I think you're asking how to blend a custom intensity image with an rgb
image. (I'm traveling and just have my phone, so you'll have to excuse my
lack of examples.)
There are several ways to do this. Basically, it's analogous to "blend
modes" in Photoshop etc.
Have a look at the matplotlib.colors.LightSource.blend_overlay and
blend_soft_light functions in the current github head. (And also
http://matplotlib.org/devdocs/examples/specialty_plots/topographic_hillsh
ading.html )
If you're working with 1.4.x, though, you won't have those functions.
However, the math is very simple. Have a look at the code in those
functions in the github head. It's basically a one liner.
You'll need both the 4-band rgba image and the 1 band intensity/hillshade
image to be floating point arrays scaled from 0-1. However, this is the
default in matplotlib.
How that helps a bit, and sorry again for the lack of examples!
Joe
OK, I understand.
Could you suggest a way to reduce that 3D array to a 2D array and plot it
with a specific colormap, while preserving the shading?
I did something similar in Matlab
https://mycarta.wordpress.com/2012/04/05/visualization-tips-for-geoscient
ists-matlab-part-ii/
But it took using some custom functions and a ton of asking and
tinkering, and I'm not quite at that level with matplotlib, so any
suggestion would be appreciated
Thanks,
Matteo
Post by Eric Firing
Colormapping occurs only when you give imshow a 2-D array of numbers to
be mapped; when you feed it a 3-D array of RGB values, it simply shows
those colors. For colormapping to occur, it must be done on a 2-D
array as a step leading up to the generation of your img_array.
Eric
Post by Matteo Niccoli
I posted a question on stackoverflow about creating with making my
own shading effect (I want to use horizontal gradient for the
shading).
http://stackoverflow.com/questions/30310002/issue-creating-map-shadin
g- in-matplotlib-imshow-by-setting-opacity-to-data-gradi
Unfortunately I cannot share the data because I am using it for a
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/sur
fa ce_shading.ipynb/%3Fdl%3D0
The shading using gradient is implemented in two ways as suggested in
the answer. What I do not understand is why the last plot comes out
with a rainbow-like colors, when I did specify cubehelix as colormap.
hsv = cl.rgb_to_hsv(img_array[:, :, :3]) hsv[:, :, 2] = tdx_n rgb =
cl.hsv_to_rgb(hsv) plt.imshow(rgb[4:-3,4:-3], cmap='cubehelix')
plt.show()
Am I doing something wrong or is this unexpected behavior; is there a
workaround?
Thanks
Matteo
-----------------------------------------------------------------------
--
-----
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
-------------------------------------------------------------------------
-----
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Matteo Niccoli
2015-05-23 16:42:36 UTC
Permalink
This stems from a previous discussion I started, please see thread below.

With reference to this notebook:
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/surface_shading.ipynb/%3Fdl%3D0
I originally thought there was an issue with the implementation of the
blending of RGB and intensity images in cells 9 to 11 using
color.rgb_to_hsv and color.hsv_to_rgb, which modified the colors in the
original colormap.
Thanks to a tip from a friend, I realized this only happens with cubehelix
only, and not with gist_earth and afmhot, as seen in cells 12 and 13.
Furthermore, this does not happen to the cubehelix when converting it to
hsv and back to rgb, as seen in cell 14, so there must be something odd
when converting cubehelix to hsv, changing the value layer, and
reconverting to rgb.
Should this be recorded as an issue on github?

Thanks
Matteo
Post by Matteo Niccoli
Joe, Eric
Thanks to both for your further comments.
I made a new notebook, this time using open source data so it can be
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/surface
_shading.ipynb/%3Fdl%3D0
https://www.dropbox.com/s/p87bojlnmad9p9j/Penobscot_HorB.txt?dl=0
The first method suggested by titusjan on stackoverflow is essentially the
same as the matplotlib.colors blend_soft_ligh suggested by Joe as it
uses the pegtop algorithm. It works nicely with the data.
The second method suggested by titusjan replaces value in hsv space with
intensity as suggested. Eric you will notce I did include the line
img_array = plt.get_cmap('cubehelix')(data_n) and yet the colormapping is
not working.
I am very keen to sort out if this is a bug in the software or a problem
in my code, and if there is a way to make it work. The reason is that this
method would allow blending three pieces of information, to create a
https://books.google.ca/books?id=dP2iACuzq34C&q=figure+20#v=snippet&q=a%2
0time%20slice%20through%20a%20survey%20acquired%20over%20the%20Central%20
Basin%20Platform%2C%20Texas%2C%20U.S.A.%2C%20using%20a%203D&f=false
Any further insight would be really appreciated.
Matteo
Post by Joe Kington
I think you're asking how to blend a custom intensity image with an rgb
image. (I'm traveling and just have my phone, so you'll have to excuse
my lack of examples.)
There are several ways to do this. Basically, it's analogous to "blend
modes" in Photoshop etc.
Have a look at the matplotlib.colors.LightSource.blend_overlay and
blend_soft_light functions in the current github head. (And also
http://matplotlib.org/devdocs/examples/specialty_plots/topographic_hill
sh ading.html )
If you're working with 1.4.x, though, you won't have those functions.
However, the math is very simple. Have a look at the code in those
functions in the github head. It's basically a one liner.
You'll need both the 4-band rgba image and the 1 band
intensity/hillshade image to be floating point arrays scaled from 0-1.
However, this is the
default in matplotlib.
How that helps a bit, and sorry again for the lack of examples!
Joe
OK, I understand.
Could you suggest a way to reduce that 3D array to a 2D array and plot
it with a specific colormap, while preserving the shading?
I did something similar in Matlab
https://mycarta.wordpress.com/2012/04/05/visualization-tips-for-geoscie
nt ists-matlab-part-ii/
But it took using some custom functions and a ton of asking and
tinkering, and I'm not quite at that level with matplotlib, so any
suggestion would be appreciated
Thanks,
Matteo
Post by Eric Firing
Colormapping occurs only when you give imshow a 2-D array of numbers
to be mapped; when you feed it a 3-D array of RGB values, it simply
shows those colors. For colormapping to occur, it must be done on a
2-D
array as a step leading up to the generation of your img_array.
Eric
Post by Matteo Niccoli
I posted a question on stackoverflow about creating with making my
own shading effect (I want to use horizontal gradient for the
shading).
http://stackoverflow.com/questions/30310002/issue-creating-map-shad
in g- in-matplotlib-imshow-by-setting-opacity-to-data-gradi
Unfortunately I cannot share the data because I am using it for a
http://nbviewer.ipython.org/urls/dl.dropbox.com/s/2pfhla9rn66lsbv/s
ur fa ce_shading.ipynb/%3Fdl%3D0
The shading using gradient is implemented in two ways as suggested
in the answer. What I do not understand is why the last plot comes
out with a rainbow-like colors, when I did specify cubehelix as
colormap.
hsv = cl.rgb_to_hsv(img_array[:, :, :3]) hsv[:, :, 2] = tdx_n rgb =
cl.hsv_to_rgb(hsv) plt.imshow(rgb[4:-3,4:-3], cmap='cubehelix')
plt.show()
Am I doing something wrong or is this unexpected behavior; is there
a workaround?
Thanks
Matteo
---------------------------------------------------------------------
--
--
-----
One dashboard for servers and applications across
Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
-----------------------------------------------------------------------
--
-----
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Eric Firing
2015-05-23 18:19:32 UTC
Permalink
Post by Matteo Niccoli
The second method suggested by titusjan replaces value in hsv space with
intensity as suggested. Eric you will notce I did include the line
img_array = plt.get_cmap('cubehelix')(data_n) and yet the colormapping is
not working.
I don't understand your conclusion that the colormapping is not working.
I don't see anything wrong with any of these plots. The two
algorithms appear to be doing exactly what they are supposed to do.

Eric
Eric Firing
2015-05-23 19:07:18 UTC
Permalink
Hi Eric
If you look at the two attached images, both have the shading as expected,
but in one case the colours have changed, from the cubehelix colors, to
rainbow colors.
Yes, the result looks more like a rainbow set, but that doesn't mean
anything is incorrect. The algorithm is doing what you are telling it
to do. The "alter V" algorithm will *always* generate colors that are
outside the original colormap. It happens that superimposing wild
variations in V on something mapped with cubehelix yields a result that
looks more rainbow-ish than if you started with some other map. This is
just because of the character of cubehelix. It doesn't mean the code is
failing--it means the algorithm is not the right one for the result you
want to achieve, or cubehelix is not a good choice for the result you
want, or both.

You might get something more to your liking if you were to start with a
colormap in which V is uniform--all variation is in H and S--and then
impose the shading on the V. Cubehelix starts with a full range of V,
so replacing V with your shading channel completely changes the set of
colors you end up with.

Eric
Matteo
Post by Eric Firing
Post by Matteo Niccoli
The second method suggested by titusjan replaces value in hsv space
with intensity as suggested. Eric you will notce I did include the line
img_array = plt.get_cmap('cubehelix')(data_n) and yet the colormapping
is not working.
I don't understand your conclusion that the colormapping is not working.
I don't see anything wrong with any of these plots. The two
algorithms appear to be doing exactly what they are supposed to do.
Eric
-------------------------------------------------------------------------
-----
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Jody Klymak
2015-05-23 20:23:23 UTC
Permalink
Post by Eric Firing
You might get something more to your liking if you were to start with a
colormap in which V is uniform--all variation is in H and S--and then
impose the shading on the V. Cubehelix starts with a full range of V,
so replacing V with your shading channel completely changes the set of
colors you end up with.
Or maybe instead of replacing hsv[:,:,2] with dip you scale it by hsv[:,:,2]:

hsv[:,:,2]=dip*hsv[:,:,2]

Cheers, Jody
Matteo Niccoli
2015-05-23 21:15:14 UTC
Permalink
Nice idea
I will try


Sent from my iPhone
Post by Jody Klymak
Post by Eric Firing
You might get something more to your liking if you were to start with a
colormap in which V is uniform--all variation is in H and S--and then
impose the shading on the V. Cubehelix starts with a full range of V,
so replacing V with your shading channel completely changes the set of
colors you end up with.
hsv[:,:,2]=dip*hsv[:,:,2]
Cheers, Jody
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-users mailing list
https://lists.sourceforge.net/lists/listinfo/matplotlib-users
Loading...