✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚑️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Plotly Express in Python: Is there a way to define your own CSS color?

Hi, Plotly community!

A nice graphing tool that you have here.
However, I have a question as a newbie using the Plotly Express choropleth visual.
Also, I would like to apologize for the length of this question in advance!

So, I am making a choropleth graph on Plotly Express (Python version) to map the Government Respond on COVID-19; particularly in Africa.

If any of you wondering about the data source, you can find it here, Oxford University data source.
For your convenience, some example of the content of this data source:

CountryName|CountryCode| Date    |...|EconomicSupportIndexForDisplay
Algeria    |   DZA     |20200101 |...| 0
Algeria    |   DZA     |20200102 |...| 0
.............................................................
Algeria    |   DZA     |20200724 |...| 50
............................................................

TLDR; there are 42 columns with 30,000+ rows; where these rows are updated daily.
However, not all of the countries in the dataset are equally up to date (source: Oxford University GitHub page).

For my case, I have already created my database of that dataset in PostgreSQL.
I have written this code so far but struggling to progress further.

import psycopg2
import pandas as pd
import plotly.express as px

''' PostgreSQL Variables '''
# PostgreSQL Login Variables (edited out)

''' PostgreSQL Connection '''
# PostgreSQL DB Connection code (edited out)

African_Query = pd.read_sql_query(
'''
# SQL Query to pull all African countries from the DB (e.g. 'Algeria, 'Angola', 'Benin', 'etc')
''', conn)
# except ('Comoros', 'Equatorial Guinea', 'Guinea Bissau', and 'Sao Tome and Principe')
# those countries were not exist in the datasource

''' Load SQL Queries into Pandas DataFrame '''
African = pd.DataFrame(African_Query,
                       columns=['all column names from the datasource'])

''' Plotly graph '''
# Government Respond - School Closing
african_figure1 = px.choropleth(African,
                                locations="countrycode",
                                color="c1_school_closing",
                                color_continuous_scale="Blues",
                                range_color=[0, 3],
                                hover_data={"c1_school_closing": False,
                                            "countrycode": False,
                                            "countryname": False},
                                hover_name="countryname",
                                labels={"c1_school_closing": "SCALE"})

african_figure1.update_layout(geo_scope='africa',
                              title_text="Government Respond - SCHOOL CLOSING")

african_figure1.show()

I wanted to change the colour used on my choropleth graph into using CSS style.
In this case, I want to use a CSS colour with the following code #4c5c73.

So far, I have been reviewing the documentation on colorscales and the choropleth.

There is indeed a trace of the use of CSS colour in choropleth_mapbox.
But, this is not what I am looking for.

Thus, Plotly community could you please help me figured out the fix for this?

Many thanks for your time and again, I apologize for the length of this question.

Best,
Aldy

Apology if this is not clear enough,

What I meant with this question if it’s possible to define your CSS colour in color_continuous_scale in choropleth graph of plotly.express

I saw an example that it is possible but it seemed to be (in my limited understanding of Plotly) possible in plotly.graph_objects and when using the followings:
(a) Contour, and
(b) Heatmap,

You can correct me on this but those are the examples that I found where it is possible to define your CSS colour.

Many thanks for your time!

@Aldy_Abe
Do you mean a colorscale with hex color codes? If this is a case you can define the colorscale like this one:

my_colorscale = [[0.0, β€˜#d6f9cf’],
[0.1, β€˜#b7e2ab’],
[0.2, β€˜#95cd89’],
[0.3, β€˜#72ba6c’],
[0.4, β€˜#43a855’],
[0.5, β€˜#11934f’],
[0.6, β€˜#097d4a’],
[0.7, β€˜#156640’],
[0.8, β€˜#195034’],
[0.9, β€˜#183924’],
[1.0, β€˜#112414’]]

The values, vals, which are mapped to the colorscale are first normalized by plotly.js, such that
norm_vals are floats in [0,1]. Hence if some of the numbers 0, 0.1, 0.2, …, 0.9, 1, are in the list (array) norm_vals, they are mapped to the corresponding color in the definition of my_colorscale. For any other number in the list norm_vals, the corresponding color is calculated by plotly.js through linear interpolation.

When you set the colorscale, either in a trace definition (Heatmap, Contour, etc) or as coloraxis_colorscale,
or when you define `fig = px.choropleth_mapbox’, just set:

colorscale= my_colorscale

respectively color_continuous_scale=my_colorscale for px.choropleth_mapbox.

If you want to convert a matplotlib colormap to a Plotly colorscale, you can call the following function:

import numpy as np
import matplotlib.cm as cm

def mpl_to_hexplotly(cmap, pl_entries=11, rdigits=2):
    # cmap  mpl or cmocean colormap 
    # rdigits - in - number of digits for rounding scale values
    scale = np.linspace(0, 1, pl_entries) #    # plotly colorscale's scale 
    colors = (cmap(scale)[:, :3]*255).astype(np.int)
    hexcolors = [f'#{c[0]:02x}{c[1]:02x}{c[2]:02x}'  for c in colors]
    pl_colorscale = [[round(s, rdigits), hc] for s, hc in zip(scale, hexcolors)]
    
    return pl_colorscale

example:

new_colorscale=  mpl_to_hexplotly(cm.RdYlBu)
1 Like

Yes, this is exactly what I am looking for.

What you are trying to say here is defining the colour shades of that particular CSS colour right?
I just tested it on my code and I get the colour that I want which is #4c5c73 (as a starting point).

So, I got that colour and all of it shades as I define here:

my_color_scale = [[0.0, '#4c5c73'], [0.1, '#445267'], [0.2, '#3C495C'], [0.3, '#354050'], 
                 [0.4, '#2D3745'], [0.5, '#262D39'], [0.6, '#1E242E'], [0.7, '#161B22'], 
                 [0.8, '#0F1217'], [0.9, '#07090B'], [1.0, '#000000']]

The result of it is this picture

Thus, whenever I wanted to define my CSS colour; I will have to define all of its shades/tints in that array list?Am I understand this correctly?

Many thanks for your time!

@Aldy_Abe
Yes you have to give, let us say 11 colors (or less or more), but it it is recomended to go from darker to lighter ones or conversely. In your plot it is difficult to distinguish the countries by color, because they are too dark.

1 Like

Thanks for confirming this.

If that is the case, how can I reverse the order of my colour scale then?

I think the in-built colour you just have to write something like color_continuous_scale='Blues_r'.
What about my defined colour scale? Or is it better to re-arrange the list of my colour scale array?

Many thanks for your time again!

@Aldy_Abe
For custom colorscales after setting
colorscale=my_colorscale #set also:
reversescale=True

does the job.

But for the px figures, if fig = px.something(),
then you must perform the following update:

fig.update_layout(coloraxis_reversescale=True)

1 Like

Many thanks for this!

I have tried and it successfully creates the reverted colour version of it. Again, thanks so much.

The result of the reverted colour:

edit: I know it’s still a bit darker, so I will see if instead using the shade code, that is using the tint code; will it look better or not.

Best,
Aldy

@empet

Just a quick update, I am using the tint code and it looks better in my opinion. I think it looks more visible now for all countries.

Many thanks for your time and guides!