Skip to content

Instantly share code, notes, and snippets.

@kwinkunks
Last active June 11, 2024 14:29
Show Gist options
  • Save kwinkunks/75c376a8299c4d66b28f91b8989ab190 to your computer and use it in GitHub Desktop.
Save kwinkunks/75c376a8299c4d66b28f91b8989ab190 to your computer and use it in GitHub Desktop.
Matplotlib colourmaps for QGIS

mpl2qgis

See script below.

Make sure the Python file is executable. Then:

$ ./mpl2qgis.py viridis bone

This writes a file colourmaps.xml. Result:

<!DOCTYPE qgis_style>
<qgis_style version="0">
<symbols/>
<colorramps>
    <colorramp type="gradient" name="viridis">
    <prop k="color1" v="68,1,84,255"/>
    <prop k="color2" v="253,231,37,255"/>
    <prop k="stops" v="0.04;71,16,99,255:0.08;72,29,111,255:0.12;71,42,122,255:0.16;69,55,129,255:0.2;65,68,135,255:0.24;60,79,138
,255:0.28;55,90,140,255:0.32;50,100,142,255:0.36;46,111,142,255:0.4;42,120,142,255:0.44;38,130,142,255:0.48;34,139,141,255:0.52;31,1
49,139,255:0.56;31,159,136,255:0.6;34,168,132,255:0.64;44,177,126,255:0.68;59,187,117,255:0.72;78,195,107,255:0.76;99,203,95,255:0.8
;122,209,81,255:0.84;149,216,64,255:0.88;176,221,47,255:0.92;202,225,31,255:0.96;229,228,25,255"/>
    </colorramp>
    <colorramp type="gradient" name="bone">
    <prop k="color1" v="0,0,0,255"/>
    <prop k="color2" v="255,255,255,255"/>
    <prop k="stops" v="0.04;9,9,12,255:0.08;18,17,24,255:0.12;26,26,37,255:0.16;35,35,49,255:0.2;45,45,62,255:0.24;53,53,74,255:0.
28;62,62,86,255:0.32;71,71,99,255:0.36;80,80,112,255:0.4;89,92,121,255:0.44;98,104,130,255:0.48;107,116,139,255:0.52;116,129,148,255
:0.56;125,141,157,255:0.6;134,154,166,255:0.64;143,166,174,255:0.68;152,179,184,255:0.72;161,191,193,255:0.76;172,202,202,255:0.8;18
5,210,210,255:0.84;200,220,220,255:0.88;214,229,229,255:0.92;228,238,237,255:0.96;241,246,246,255"/>
    </colorramp>
</colorramps>
</qgis_style>

To install the color ramps, go to QGIS > Settings > Style Manager > Color ramp, hit the green + sign, and select the file.

Why

https://twitter.com/AndyDoggerBank/status/1085527532470968321

Inspiration

http://rocksandwater.net/blog/2016/07/qgis_perceptually_uniform_colorramps/

#!/usr/bin/env python
#-*- coding:utf-8 -*-
"""
Converts matplotlib colourmaps to QGIS colourmaps.
Matt Hall, 2019, released into public domain / CC-0.
"""
import sys
from matplotlib import colormaps as mpc
XML = """<!DOCTYPE qgis_style>
<qgis_style version="0">
<symbols/>
<colorramps>
{0}
</colorramps>
</qgis_style>"""
CRAMP = """ <colorramp type="gradient" name="{name}">
<prop k="color1" v="{color1}"/>
<prop k="color2" v="{color2}"/>
<prop k="stops" v="{stops}"/>
</colorramp>"""
def get_rgba(name, value):
"""Get (R, G, B, A) for a value on a matplotlib colormap.
"""
cmap = mpc.get_cmap(name)
rgba = [str(int(round(255*v, 0))) for v in cmap(value)]
return rgba
def qgis_xml(name):
params = {'name': name}
params['color1'] = ','.join(get_rgba(name, 0.0))
params['color2'] = ','.join(get_rgba(name, 1.0))
stops = []
for v in range(4, 100, 4):
v /= 100
s = f'{v};'
s += ','.join(get_rgba(name, v))
stops.append(s)
params['stops'] = ':'.join(stops)
return CRAMP.format(**params)
def mpl2qgis(names):
cramps = '\n'.join(qgis_xml(name) for name in names)
return XML.format(cramps)
if __name__ == '__main__':
with open('colourmaps.xml', 'w') as f:
f.write(mpl2qgis(sys.argv[1:]))
@AkliDif
Copy link

AkliDif commented Aug 21, 2023

Hello, I was wondering if you know how to achieve the inverse. I mean, how can you use a QgsColorRamp in a Matplotlib graph instead of a Matplotlib colormap?

@jpdarela
Copy link

Thank you for the genuinely nice utility. I would suggest change the import in line 9 to:

from matplotlib import colormaps as mpc

This is because of the following deprecation warning:

MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.

I'm using matplotlib 3.7.2 in python 3.11.4.

@kwinkunks
Copy link
Author

@jpdarela Thank you! Done.

@AkliDif Assuming you can find the XML file, you would have to parse it into an array and then do something like this

If all you have is an image of the colourmap, then unmap might be able to recover a matplotlib colourmap from it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment