2

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 enter image description here

Darkstar Dream
  • 1,649
  • 1
  • 12
  • 23
  • Your title asks how to put the legend outside the graph, but your question seems to be how to make the colours distinguishable, could you be more clear? – Nathan Jan 21 '20 at 11:54
  • 1
    @Nathan I am sorry I forgot to edit title now I have edited it – Darkstar Dream Jan 21 '20 at 11:57
  • Could you also add an example df so that it's easier to recreate your problem? – Nathan Jan 21 '20 at 11:58
  • The answer you link to explains why you get this error in the last paragraph. There are also other answers in that thread. – ImportanceOfBeingErnest Jan 21 '20 at 12:10
  • @ImportanceOfBeingErnest yeah I know but they are for subplots right and they are applying that by iterating(individually) how gonna convert that for my code I don't have any idea if you can modify that for me then that will great for me – Darkstar Dream Jan 22 '20 at 07:39

1 Answers1

0

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()

example plot

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • There's a problem I have 53 columns and little different shade of same color is not effective to distinguish is there any other way – Darkstar Dream Jan 22 '20 at 07:59
  • In the example data of your question, there are only 5 groups. I invested time to create an example similar to the example image. Your question doesn't mention 53 columns. Maybe a stacked bar chart isn't the most adequate way to visualize your data? – JohanC Jan 22 '20 at 08:03
  • The way to go, is to group together similar complaints to strongly reduce the number of groups. Inside each group, you could use different tints of the same color to distinguish them. – JohanC Jan 22 '20 at 08:08
  • I am really thankful for your help. Actually I have a problem to find-out is there any relation between the complaints and the location so I thought that to find this out stack bar chart is a good way as we can see if any complaint is only from one or from few cities if that the case it means yes there is relation and vice-versa so is there another way I can go with – Darkstar Dream Jan 22 '20 at 08:12
  • 1
    What you typically have, is that different cities use different criteria to define and describe their complaints. Even different police offices in the same city will name the same complaint differently. – JohanC Jan 22 '20 at 08:18