seaborn multiple histplot color palette - colors

The following example code:
import seaborn as sns
planets = sns.load_dataset("planets")
sns.histplot(
planets, x="year", y="distance",
bins=30, discrete=(True, False), log_scale=(False, True),
)
produces this plot
How can I change the color palette being used here? I'd like to use something like
sns.color_palette("Spectral", as_cmap=True)
to show more clear contrast of different levels (the plot I really want has a larger number of histograms than this example, and it's hard to see the contrast with only blue hues)

You can use the cmap parameter
sns.histplot(
planets, x="year", y="distance",
bins=30, discrete=(True, False), log_scale=(False, True),
cmap="Spectral", cbar=True,
)
But note that Spectral specifically is a diverging palette and not really appropriate for count data.

Related

Visualise different areas on the axes in a matplotlib python plot

I would like to generate a plot like this in Python:
I am primarily interested in the possibility of inserting the pink and green areas into the plot in order to highlight different ranges. Area1-3 should get different colours and names later.
Thanks a lot!
PS: my Phython code atm is:
fig3, ax3 = plt.subplots()
plot3 = ax3.scatter(nocore[0,:],nocore[1,:],c=nocore[2,:], s=3, cmap='seismic', label='Group X')
ax3.set_xlabel("X")
ax3.set_ylabel("Y")
ax3.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15))
plt.ylim(ymin=45, ymax=362)
plt.ylim(ymin=0, ymax=320)
fig3.colorbar(plot3, ax=ax3, label ='Colorrange')
plt.savefig('nocore.png', dpi=300)
plt.show()
Not sure what to do or what is the best way of doing it.

How to change color in pie chart using Matplotlib

I am trying to make v1 as blue, v2 as orange, v3 green and v4 as light grey
I tried going through documentation but cannot understand how to define color in piechart. Thank you for help.
I am using few line of codes of generate a piechart
where vol1 = v1,v2,v3,v4
plt.pie(vol1,labels = vollabels, autopct="%0.2f%%")
plt.legend(title="Normalized Volumes",loc="upper left", fontsize=14)
plt.axis
plt.show()
If you want to have control over which colors your pie chart contains, while at the same time not fall out of matplotlib's convenient handling of colour maps, you might want to have a look at documentation example Nested pie charts. Extracted highlights:
import matplotlib.pyplot as plt
import numpy as np
Retrieve a named colour map and "hand-pick", using a numbered range, suitable colors. The index picking in inner_colors matches hues for a larger numbers of data points in the inner circle:
cmap = plt.get_cmap("tab20c")
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap(np.array([1, 2, 5, 6, 9, 10]))
The actual plotting, including some customisation, is then straightforward:
fig, ax = plt.subplots()
size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])
ax.pie(vals.sum(axis=1), radius=1, colors=outer_colors,
wedgeprops=dict(width=size, edgecolor='w'))
ax.pie(vals.flatten(), radius=1-size, colors=inner_colors,
wedgeprops=dict(width=size, edgecolor='w'))
Bonus content in the linked location: how to achieve the same result using a bar plot, but using polar coordinates. That way, one has more flexibility over the exact design, if one's goals diverge from the defaults assumed in pie.

How to set unique color for each labels of legends in stacked bar graph [duplicate]

I have many legends in my stacked bar plot and I noticed that in legend the color is repeating so it's hard for me to distinguish the true value in the graph according to the legends so, I want to set the unique color for each value in the legend and for this, I did lots of research some are not working and some are quite hard to understand example this
when I used this I got an error that 'AxesSubplot' object has no attribute 'set_color_cycle' so is there an easy and effective way
I don't want the code that applies color for each element individually because my dataset is large and here my code for more detail about my plot
eg
#suppose I have data of few cites and their complaints
city = ['NEW YORK', 'ASTORIA', 'BRONX', 'BRONX', 'ELMHURST', 'BROOKLYN',
'NEW YORK', 'BRONX', 'KEW GARDENS', 'BROOKLYN']
complaints = ['Noise - Street/Sidewalk', 'Blocked Driveway', 'Blocked Driveway',
'Illegal Parking', 'Illegal Parking', 'Illegal Parking',
'Illegal Parking', 'Blocked Driveway', 'Illegal Parking',
'Blocked Driveway']
# and from this I have created a stack bar chart
cmpltnt_rela = test2.groupby(['City', 'Complaint Type']).size().unstack().fillna(0).plot(kind='bar', legend = True, stacked=True)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5),ncol=2)
cmpltnt_rela.plot(figsize=(18,14))
and its result looks something like this where you can notice legend's element color
You might create a list of colors with the same length as the number of unique complaints. For example gist_ncar. In the code I shuffled the order of the colors to make it less likely that similar colors are near.
Note that it is very hard to have more than 20 colors that are different enough visually. Different people and different monitors may cause colors hard to distinguish.
This and this post provide more ideas to choose enough colors. In your case it might be interesting to color similar complaints with similar hues.
As your example code doesn't provide enough data, the code below generates some random numbers.
import pandas as pd
from matplotlib import pyplot as plt
import random
import matplotlib as mpl
city = ['Londen', 'Paris', 'Rome', 'Brussels', 'Cologne', 'Madrid',
'Athens', 'Geneva', 'Oslo', 'Barcelona', 'Berlin']
complaints = list('abcdefghijklmnopqrstuv')
N = 100
city_column = random.choices(city, k=N)
complaints_column = random.choices(complaints, k=N)
test2 = pd.DataFrame({'City': city_column, 'Complaint Type': complaints_column})
# take a colormap with many different colors and sample it at regular intervals
cmap = plt.cm.gist_rainbow
norm = mpl.colors.Normalize(vmin=0, vmax=len(complaints) - 1)
colors = [cmap(norm(i)) for i in range(len(complaints))]
# create a stack bar chart
cmpltnt_rela = test2.groupby(['City', 'Complaint Type']).size().unstack().fillna(0).plot(kind='bar',
legend=True, stacked=True, color=colors)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), ncol=2)
cmpltnt_rela.plot(figsize=(18, 14))
plt.tick_params('x', labelrotation=30)
plt.tight_layout()
plt.show()

Creating a structured grid of subplots with Seaborn FacetGrid

My attempt to use FacetGrid in Seaborn does not produces the expected results.
Moreover, I would like to control the white space in the grid.
My data and code is the following:
toy.to_json()
'{"has_cus_id_but_not_acc_id":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":1,"19":0,"20":0,"21":0,"22":1,"23":0,"24":0,"25":1,"26":0,"27":1,"28":0,"29":1,"30":0,"31":1,"32":0,"33":1,"34":0,"35":1,"36":0,"37":1,"38":0,"39":0,"40":1,"41":1,"42":0,"43":1,"44":0,"45":1,"46":0,"47":1,"48":0,"49":1,"50":0,"51":1,"52":0,"53":1,"54":0,"55":1,"56":0,"57":1,"58":0,"59":1,"60":0,"61":1,"62":0,"63":1,"64":0,"65":1,"66":0,"67":1,"68":0,"69":1,"70":0,"71":1,"72":0,"73":1,"74":0,"75":1,"76":0,"77":0,"78":1,"79":0,"80":1,"81":0,"82":0,"83":1,"84":0,"85":1},"reg_year":{"0":2014.0,"1":2014.0,"2":2014.0,"3":2014.0,"4":2014.0,"5":2014.0,"6":2014.0,"7":2014.0,"8":2015.0,"9":2015.0,"10":2015.0,"11":2015.0,"12":2015.0,"13":2015.0,"14":2015.0,"15":2015.0,"16":2015.0,"17":2016.0,"18":2016.0,"19":2016.0,"20":2016.0,"21":2016.0,"22":2016.0,"23":2016.0,"24":2016.0,"25":2016.0,"26":2016.0,"27":2016.0,"28":2016.0,"29":2016.0,"30":2016.0,"31":2016.0,"32":2016.0,"33":2016.0,"34":2016.0,"35":2016.0,"36":2016.0,"37":2016.0,"38":2017.0,"39":2017.0,"40":2017.0,"41":2017.0,"42":2017.0,"43":2017.0,"44":2017.0,"45":2017.0,"46":2017.0,"47":2017.0,"48":2017.0,"49":2017.0,"50":2017.0,"51":2017.0,"52":2017.0,"53":2017.0,"54":2017.0,"55":2017.0,"56":2017.0,"57":2017.0,"58":2017.0,"59":2017.0,"60":2018.0,"61":2018.0,"62":2018.0,"63":2018.0,"64":2018.0,"65":2018.0,"66":2018.0,"67":2018.0,"68":2018.0,"69":2018.0,"70":2018.0,"71":2018.0,"72":2018.0,"73":2018.0,"74":2018.0,"75":2018.0,"76":2018.0,"77":2018.0,"78":2018.0,"79":2018.0,"80":2018.0,"81":2018.0,"82":2019.0,"83":2019.0,"84":2019.0,"85":2019.0},"reg_month":{"0":3.0,"1":5.0,"2":6.0,"3":7.0,"4":9.0,"5":10.0,"6":11.0,"7":12.0,"8":1.0,"9":3.0,"10":5.0,"11":6.0,"12":7.0,"13":8.0,"14":9.0,"15":11.0,"16":12.0,"17":1.0,"18":1.0,"19":2.0,"20":3.0,"21":4.0,"22":4.0,"23":5.0,"24":6.0,"25":6.0,"26":7.0,"27":7.0,"28":8.0,"29":8.0,"30":9.0,"31":9.0,"32":10.0,"33":10.0,"34":11.0,"35":11.0,"36":12.0,"37":12.0,"38":1.0,"39":2.0,"40":2.0,"41":3.0,"42":4.0,"43":4.0,"44":5.0,"45":5.0,"46":6.0,"47":6.0,"48":7.0,"49":7.0,"50":8.0,"51":8.0,"52":9.0,"53":9.0,"54":10.0,"55":10.0,"56":11.0,"57":11.0,"58":12.0,"59":12.0,"60":1.0,"61":1.0,"62":2.0,"63":2.0,"64":3.0,"65":3.0,"66":4.0,"67":4.0,"68":5.0,"69":5.0,"70":6.0,"71":6.0,"72":7.0,"73":7.0,"74":8.0,"75":8.0,"76":9.0,"77":10.0,"78":10.0,"79":11.0,"80":11.0,"81":12.0,"82":1.0,"83":1.0,"84":2.0,"85":2.0},"Total_Revenue":{"0":35852.02,"1":2623.97,"2":3526.67,"3":21466.71,"4":72784.1200000003,"5":103921.2899999999,"6":10852.87,"7":16522.07,"8":7443.76,"9":68962.1600000002,"10":10956.38,"11":193856.8799999985,"12":110766.6099999997,"13":123861.8599999987,"14":2722.34,"15":303488.6900000007,"16":6876.58,"17":17729.5,"18":4687.93,"19":26914.06,"20":2228.12,"21":15708.93,"22":859.58,"23":19164.89,"24":163164.4799999995,"25":33180.7300000001,"26":10033.01,"27":1114.48,"28":462613.2900000042,"29":9822.95,"30":70901.4400000003,"31":22370.29,"32":46711.8900000002,"33":2335.02,"34":7259.28,"35":11.83,"36":13590.51,"37":7677.77,"38":282.01,"39":358522.7900000003,"40":5844.0,"41":7027.28,"42":1908.71,"43":4032.35,"44":11072.6,"45":3973.15,"46":30706.23,"47":2644.13,"48":23831.75,"49":670.12,"50":6949.54,"51":4687.7,"52":9672.69,"53":7333.01,"54":12814.33,"55":689.39,"56":6962.86,"57":2283.16,"58":1259.5,"59":224.84,"60":12812.12,"61":247.68,"62":25452.65,"63":1245.02,"64":24211.36,"65":5255.25,"66":28402.76,"67":9148.55,"68":14822.61,"69":345.37,"70":12408.13,"71":989.93,"72":10601.33,"73":730.32,"74":169020.5000000001,"75":697.54,"76":3862038.6799997138,"77":6148750.9899984254,"78":194.06,"79":2379382.4500000761,"80":1174.11,"81":1729567.9000000793,"82":889650.029999995,"83":95.8,"84":415996.6999999974,"85":654.78}}'
g = sns.FacetGrid(toy, col='has_cus_id_but_not_acc_id', hue='reg_year')
g.map(sns.barplot, 'reg_month', 'Total_Revenue')
g.add_legend();
If I use bar in pyplot I get this:
g = sns.FacetGrid(toy, col='has_cus_id_but_not_acc_id', hue='reg_year')
g.map(plt.bar, 'reg_month', 'Total_Revenue')
g.add_legend();
Again, I would like to be able to define the white space of the grid.
In addition I would not like to have the bars stacked one over the other but rather one next to the other.
Some values of the year 2018 are really large compared to the any of the values where has_cus_id_but_not_acc_id is 1. Hence the right plot is almost empty. It might make sense to use a logarithmic scale.
Now you have 6 years, so each month would need to show 6 bars next to each other. That will make bars pretty small and does not let the chart be easily readable. Still it's possible.
The following does not use seaborn, but pandas and matplotlib:
import matplotlib.pyplot as plt
import pandas as pd
toy = '{"has_cus_id_but_not_acc_id":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":1,"19":0,"20":0,"21":0,"22":1,"23":0,"24":0,"25":1,"26":0,"27":1,"28":0,"29":1,"30":0,"31":1,"32":0,"33":1,"34":0,"35":1,"36":0,"37":1,"38":0,"39":0,"40":1,"41":1,"42":0,"43":1,"44":0,"45":1,"46":0,"47":1,"48":0,"49":1,"50":0,"51":1,"52":0,"53":1,"54":0,"55":1,"56":0,"57":1,"58":0,"59":1,"60":0,"61":1,"62":0,"63":1,"64":0,"65":1,"66":0,"67":1,"68":0,"69":1,"70":0,"71":1,"72":0,"73":1,"74":0,"75":1,"76":0,"77":0,"78":1,"79":0,"80":1,"81":0,"82":0,"83":1,"84":0,"85":1},"reg_year":{"0":2014.0,"1":2014.0,"2":2014.0,"3":2014.0,"4":2014.0,"5":2014.0,"6":2014.0,"7":2014.0,"8":2015.0,"9":2015.0,"10":2015.0,"11":2015.0,"12":2015.0,"13":2015.0,"14":2015.0,"15":2015.0,"16":2015.0,"17":2016.0,"18":2016.0,"19":2016.0,"20":2016.0,"21":2016.0,"22":2016.0,"23":2016.0,"24":2016.0,"25":2016.0,"26":2016.0,"27":2016.0,"28":2016.0,"29":2016.0,"30":2016.0,"31":2016.0,"32":2016.0,"33":2016.0,"34":2016.0,"35":2016.0,"36":2016.0,"37":2016.0,"38":2017.0,"39":2017.0,"40":2017.0,"41":2017.0,"42":2017.0,"43":2017.0,"44":2017.0,"45":2017.0,"46":2017.0,"47":2017.0,"48":2017.0,"49":2017.0,"50":2017.0,"51":2017.0,"52":2017.0,"53":2017.0,"54":2017.0,"55":2017.0,"56":2017.0,"57":2017.0,"58":2017.0,"59":2017.0,"60":2018.0,"61":2018.0,"62":2018.0,"63":2018.0,"64":2018.0,"65":2018.0,"66":2018.0,"67":2018.0,"68":2018.0,"69":2018.0,"70":2018.0,"71":2018.0,"72":2018.0,"73":2018.0,"74":2018.0,"75":2018.0,"76":2018.0,"77":2018.0,"78":2018.0,"79":2018.0,"80":2018.0,"81":2018.0,"82":2019.0,"83":2019.0,"84":2019.0,"85":2019.0},"reg_month":{"0":3.0,"1":5.0,"2":6.0,"3":7.0,"4":9.0,"5":10.0,"6":11.0,"7":12.0,"8":1.0,"9":3.0,"10":5.0,"11":6.0,"12":7.0,"13":8.0,"14":9.0,"15":11.0,"16":12.0,"17":1.0,"18":1.0,"19":2.0,"20":3.0,"21":4.0,"22":4.0,"23":5.0,"24":6.0,"25":6.0,"26":7.0,"27":7.0,"28":8.0,"29":8.0,"30":9.0,"31":9.0,"32":10.0,"33":10.0,"34":11.0,"35":11.0,"36":12.0,"37":12.0,"38":1.0,"39":2.0,"40":2.0,"41":3.0,"42":4.0,"43":4.0,"44":5.0,"45":5.0,"46":6.0,"47":6.0,"48":7.0,"49":7.0,"50":8.0,"51":8.0,"52":9.0,"53":9.0,"54":10.0,"55":10.0,"56":11.0,"57":11.0,"58":12.0,"59":12.0,"60":1.0,"61":1.0,"62":2.0,"63":2.0,"64":3.0,"65":3.0,"66":4.0,"67":4.0,"68":5.0,"69":5.0,"70":6.0,"71":6.0,"72":7.0,"73":7.0,"74":8.0,"75":8.0,"76":9.0,"77":10.0,"78":10.0,"79":11.0,"80":11.0,"81":12.0,"82":1.0,"83":1.0,"84":2.0,"85":2.0},"Total_Revenue":{"0":35852.02,"1":2623.97,"2":3526.67,"3":21466.71,"4":72784.1200000003,"5":103921.2899999999,"6":10852.87,"7":16522.07,"8":7443.76,"9":68962.1600000002,"10":10956.38,"11":193856.8799999985,"12":110766.6099999997,"13":123861.8599999987,"14":2722.34,"15":303488.6900000007,"16":6876.58,"17":17729.5,"18":4687.93,"19":26914.06,"20":2228.12,"21":15708.93,"22":859.58,"23":19164.89,"24":163164.4799999995,"25":33180.7300000001,"26":10033.01,"27":1114.48,"28":462613.2900000042,"29":9822.95,"30":70901.4400000003,"31":22370.29,"32":46711.8900000002,"33":2335.02,"34":7259.28,"35":11.83,"36":13590.51,"37":7677.77,"38":282.01,"39":358522.7900000003,"40":5844.0,"41":7027.28,"42":1908.71,"43":4032.35,"44":11072.6,"45":3973.15,"46":30706.23,"47":2644.13,"48":23831.75,"49":670.12,"50":6949.54,"51":4687.7,"52":9672.69,"53":7333.01,"54":12814.33,"55":689.39,"56":6962.86,"57":2283.16,"58":1259.5,"59":224.84,"60":12812.12,"61":247.68,"62":25452.65,"63":1245.02,"64":24211.36,"65":5255.25,"66":28402.76,"67":9148.55,"68":14822.61,"69":345.37,"70":12408.13,"71":989.93,"72":10601.33,"73":730.32,"74":169020.5000000001,"75":697.54,"76":3862038.6799997138,"77":6148750.9899984254,"78":194.06,"79":2379382.4500000761,"80":1174.11,"81":1729567.9000000793,"82":889650.029999995,"83":95.8,"84":415996.6999999974,"85":654.78}}'
df = pd.read_json(toy)
df['reg_year'].astype(int)
u = df["has_cus_id_but_not_acc_id"].unique()
y = df['reg_year'].unique()
fig, axes = plt.subplots(1,len(u), sharey=True)
axes[0].set_yscale("log")
for ax, (n, grp) in zip(axes.flat, df.groupby("has_cus_id_but_not_acc_id")):
piv = grp.pivot('reg_month', 'reg_year', 'Total_Revenue')
empty = pd.DataFrame(index=range(1,12), columns=y)
empty.combine_first(piv).plot.bar(ax=ax, width=0.8, legend=False)
axes[1].legend()
plt.show()

specify color in seaborn catplot

I would like to specify the color of particular observations using seaborn catplot. In a made up exemple:
import seaborn as sns
import random as r
name_list=['pepe','Fabrice','jim','Michael']
country_list=['spain','France','uk','Uruguay']
favourite_color=['green','blue','red','white']
df=pd.DataFrame({'name':[r.choice(name_list) for n in range(100)],
'country':[r.choice(country_list) for n in range(100)],
'fav_color':[r.choice(favourite_color) for n in range(100)],
'score':np.random.rand(100),
})
sns.catplot(x='fav_color',
y='score',
col='country',
col_wrap=2,
data=df,
kind='swarm')
I would like to colour (or mark in another distinctive way, it could be the marker) all the observations with the name 'pepe'. How I could do that ? The other colors I dont mind, it would be better if they are all the same.
You can achieve the results you want by adding a boolean column to the dataframe and using it as the hue parameter of the catplot() call. This way you will obtain the results with two colours (one for pepe observations and one for the rest). Results can be seen here:
Also, the parameter legend=False should be set since otherwise the legend for is_pepe will appear on the side.
The code would be as below:
df['is_pepe'] = df['name'] == 'pepe'
ax = sns.catplot(x='fav_color',
y='score',
col='country',
col_wrap=2,
data=df,
kind='swarm',
hue='is_pepe',
legend=False)
Furthermore, you can specify the two colours you want for the two kinds of observations (pepe and not-pepe) using the parameter palette and the top-level function sns.color_palette() as shown below:
ax = sns.catplot(x='fav_color',
y='score',
col='country',
col_wrap=2,
data=df,
kind='swarm',
hue='is_pepe',
legend=False,
palette=sns.color_palette(['green', 'blue']))
Obtaining this results:

Resources