Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib graphing distribution with two colors

The goal here is to color value above a certain threshold into one color and values below this threshold into another color. The code below tries to just separate it into two histographs but it only looks balanced if the threshold is at 50%. I'm assuming I must play around with the discreetlevel variable.

finalutilityrange is some vector with a bunch of values(you must generate it to test the code), which I am trying to graph. The value deter is the value that determines whether they will be blue or red. discreetlevel is just the amount of bins I would want.

import random
import numpy as np
import matplotlib.pyplot as plt

discreetlevel = 10
deter = 2

for x in range(0,len(finalutilityrange)):
    if finalutilityrange[x-1]>=deter:
        piraterange.append(finalutilityrange[x-1])
    else:
        nonpiraterange.append(finalutilityrange[x-1])

plt.hist(piraterange,bins=discreetlevel,normed=False,cumulative=False,color = 'b')
plt.hist(nonpiraterange,bins=discreetlevel),normed=False,cumulative=False,color = 'r')
plt.title("Histogram")
plt.xlabel("Utlity")
plt.ylabel("Probability")
plt.show()
like image 604
Dio Avatar asked Sep 01 '25 22:09

Dio


1 Answers

This solution is a bit more complex than @user2699's. I am just presenting it for completeness. You have full control over the patch objects that hist returns, so if you can ensure that the threshold you are using is exactly on a bin edge, it is easy to change to color of selected patches. You can do this because hist can accept a sequence of bin edges as the bins parameter.

import numpy as np
from matplotlib import pyplot as plt 

# Make sample data
finalutilityrange = np.random.randn(100)
discreetlevel = 10
deter = 0.2

# Manually create `discreetlevel` bins anchored to  `deter`
binsAbove = round(discreetlevel * np.count_nonzero(finalutilityrange > deter) / finalutilityrange.size)
binsBelow = discreetlevel - binsAbove
binwidth = max((finalutilityrange.max() - deter) / binsAbove,
               (deter - finalutilityrange.min()) / binsBelow)
bins = np.concatenate([
           np.arange(deter - binsBelow * binwidth, deter, binwidth),
           np.arange(deter, deter + (binsAbove + 0.5) * binwidth, binwidth)
])

# Use the bins to make a single histogram
h, bins, patches = plt.hist(finalutilityrange, bins, color='b')

# Change the appropriate patches to red
plt.setp([p for p, b in zip(patches, bins) if b >= deter], color='r')

The result is a homogenous histogram with bins of different colors:

enter image description here

The bins may be a tad wider than if you did not anchor to deter. Either the first or last bin will generally go a little past the edge of the data.

like image 187
Mad Physicist Avatar answered Sep 04 '25 00:09

Mad Physicist