python distplot with color by values - python

I wany to create a dist plot (preferably using seaborn) with different colors to different range of values.
I have the vector:
[3,1,2,3,5,6,8,0,0,5,7,0,1, 0.2]
And I want to create a distplot such that all the parts with range 0 to 1 will be red and all the other will be blue.
What is the best way to do so?

I don't know if there is an easy way in seaborn to do this but doing the plot yourself is probably much easier. First you need to get equally sized bins (if you want that) such that the plot looks homogenous (np.histogram). Afterwards it's just a single numpy filter on your observations and the plot.
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
x = np.array([3,1,2,3,5,6,8,0,0,5,7,0,1, 0.2])
# make equal binning through the range, you can adapt the bin size here
counts, bins = np.histogram(x, bins=10)
# here we do the filtering and split the observations based on your color code
x1 = x[(x <= 1) & (x >= 0)]
x2 = x[~((x <= 1) & (x >= 0))]
# finally, do the plot
f, ax = plt.subplots()
ax.hist(x1, bins=bins, color="tab:red")
ax.hist(x2, bins=bins, color="tab:blue")
ax.set(xlabel="Measurement", ylabel="Counts", title="histogram with 2 colors")
sns.despine()
Gives you:

I think you need a scatter plot. In that case, you can try the following solution. Here you first create a column of colors based on your condition and then assign those colors to the scatter plot.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = np.array([3, 1, 2, 3, 5, 6, 8, 0, 0, 5, 7, 0,1, 0.2])
df = pd.DataFrame({'data':data}).reset_index()
df['colors'] = np.where(data<1, 'red', 'blue')
plt.scatter(df['index'], df['data'], c=df['colors'])
Alternative would be to plot directly using DataFrame
data = np.array([3, 1, 2, 3, 5, 6, 8, 0, 0, 5, 7, 0,1, 0.2])
df = pd.DataFrame({'data':data}).reset_index()
colors = np.where(data<1, 'red', 'blue')
df.plot(kind='scatter', x='index', y='data',c=colors)

Related

Vertical and Horizontal figures on one plot

I would like to create sth like the following graph in matplotlib:
I have x = [0, 1, ..., 10], and for each x I have values from range [0, 60]. Lets say that the black line is the quantile of values for a given i from range x. For selected i I want to add horizontally histogram (with parameter density = True) like in the picture with the possibility to control the width of this histogram (in the picture it goes from 2 to 5 but I would like to set fixed width). How can I do that?
Yes, this is relatively straightforward with inset_axes:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.random.randn(100)
ax.plot(x)
ylim = ax.get_ylim()
histax = ax.inset_axes([0.3, 0, 0.2, 1], transform=ax.transAxes)
histax.hist(x, orientation='horizontal', alpha=0.5 )
histax.set_facecolor('none')
histax.set_ylim(ylim)
plt.show()
You will probably want to clean up the axes etc, but that is the general idea.

How to add counts of points as a label in a sparse scatter plot

I have sparse scatter plot to visualize the comparison of predicted vs actual values. The range of the values are 1-4 and there are no decimal points.
I have tried plotly so far with hte following code (but I can also use a matplotlib solution):
my_scatter = go.Scatter(
x = y_actual, y = y_pred, mode = 'markers',
marker = dict(color = 'rgb(240, 189, 89)', opacity=0.5)
)
This prints the graph nicely (see below). I use opacity to see the density at each point. I.e. if two points lie on top of each other, the point will be shown in darker color. However, this is not explanatory enough. Is it possible to add the counts at each point as a label? There are some overlaps at certain intersections. I want to display how many points intersects. Can this be done automatically using matplotlib or plotly?
This answer uses matplotlib.
To answer the initial question first: You need to find out how often the data produces a point at a given coordinate to be able to annotate the points. If all values are integers this can easily be done using a 2d histogram. Out of the hstogram one would then select only those bins where the count value is nonzero and annotate the respective values in a loop:
x = [3, 0, 1, 2, 2, 0, 1, 3, 3, 3, 4, 1, 4, 3, 0]
y = [1, 0, 4, 3, 2, 1, 4, 0, 3, 0, 4, 2, 3, 3, 1]
import matplotlib.pyplot as plt
import numpy as np
x = np.array(x)
y = np.array(y)
hist, xbins,ybins = np.histogram2d(y,x, bins=range(6))
X,Y = np.meshgrid(xbins[:-1], ybins[:-1])
X = X[hist != 0]; Y = Y[hist != 0]
Z = hist[hist != 0]
fig, ax = plt.subplots()
ax.scatter(x,y, s=49, alpha=0.4)
for i in range(len(Z)):
ax.annotate(str(int(Z[i])), xy=(X[i],Y[i]), xytext=(4,0),
textcoords="offset points" )
plt.show()
You may then decide not to plot all points but the result from the histogramming which offers the chance to change the color and size of the scatter points,
ax.scatter(X,Y, s=(Z*20)**1.4, c = Z/Z.max(), cmap="winter_r", alpha=0.4)
Since all values are integers, you may also opt for an image plot,
fig, ax = plt.subplots()
ax.imshow(hist, cmap="PuRd")
for i in range(len(Z)):
ax.annotate(str(int(Z[i])), xy=(X[i],Y[i]), xytext=(0,0), color="w",
ha="center", va="center", textcoords="offset points" )
Without the necesity to calculate the number of occurances, another option is to use a hexbin plot. This gives slightly inaccurate positions of the dots, du to the hexagonal binning, but I still wanted to mention this option.
import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np
x = np.array(x)
y = np.array(y)
fig, ax = plt.subplots()
cmap = plt.cm.PuRd
cmaplist = [cmap(i) for i in range(cmap.N)]
cmaplist[0] = (1.0,1.0,1.0,1.0)
cmap = matplotlib.colors.LinearSegmentedColormap.from_list('mcm',cmaplist, cmap.N)
ax.hexbin(x,y, gridsize=20, cmap=cmap, linewidth=0 )
plt.show()

Suggestions to plot overlapping lines in matplotlib?

Does anybody have a suggestion on what's the best way to present overlapping lines on a plot? I have a lot of them, and I had the idea of having full lines of different colors where they don't overlap, and having dashed lines where they do overlap so that all colors are visible and overlapping colors are seen.
But still, how do I that.
I have the same issue on a plot with a high degree of discretization.
Here the starting situation:
import matplotlib.pyplot as plt
grid=[x for x in range(10)]
graphs=[
[1,1,1,4,4,4,3,5,6,0],
[1,1,1,5,5,5,3,5,6,0],
[1,1,1,0,0,3,3,2,4,0],
[1,2,4,4,3,2,3,2,4,0],
[1,2,3,3,4,4,3,2,6,0],
[1,1,3,3,0,3,3,5,4,3],
]
for gg,graph in enumerate(graphs):
plt.plot(grid,graph,label='g'+str(gg))
plt.legend(loc=3,bbox_to_anchor=(1,0))
plt.show()
No one can say where the green and blue lines run exactly
and my "solution"
import matplotlib.pyplot as plt
grid=[x for x in range(10)]
graphs=[
[1,1,1,4,4,4,3,5,6,0],
[1,1,1,5,5,5,3,5,6,0],
[1,1,1,0,0,3,3,2,4,0],
[1,2,4,4,3,2,3,2,4,0],
[1,2,3,3,4,4,3,2,6,0],
[1,1,3,3,0,3,3,5,4,3],
]
for gg,graph in enumerate(graphs):
lw=10-8*gg/len(graphs)
ls=['-','--','-.',':'][gg%4]
plt.plot(grid,graph,label='g'+str(gg), linestyle=ls, linewidth=lw)
plt.legend(loc=3,bbox_to_anchor=(1,0))
plt.show()
I am grateful for suggestions on improvement!
Just decrease the opacity of the lines so that they are see-through. You can achieve that using the alpha variable. Example:
plt.plot(x, y, alpha=0.7)
Where alpha ranging from 0-1, with 0 being invisible.
imagine your panda data frame is called respone_times, then you can use alpha to set different opacity for your graphs. Check the picture before and after using alpha.
plt.figure(figsize=(15, 7))
plt.plot(respone_times,alpha=0.5)
plt.title('a sample title')
plt.grid(True)
plt.show()
Depending on your data and use case, it might be OK to add a bit of random jitter to artificially separate the lines.
from numpy.random import default_rng
import pandas as pd
rng = default_rng()
def jitter_df(df: pd.DataFrame, std_ratio: float) -> pd.DataFrame:
"""
Add jitter to a DataFrame.
Adds normal distributed jitter with mean 0 to each of the
DataFrame's columns. The jitter's std is the column's std times
`std_ratio`.
Returns the jittered DataFrame.
"""
std = df.std().values * std_ratio
jitter = pd.DataFrame(
std * rng.standard_normal(df.shape),
index=df.index,
columns=df.columns,
)
return df + jitter
Here's a plot of the original data from Markus Dutschke's example:
And here's the jittered version, with std_ratio set to 0.1:
Replacing solid lines by dots or dashes works too
g = sns.FacetGrid(data, col='config', row='outputs', sharex=False)
g.map_dataframe(sns.lineplot, x='lag',y='correlation',hue='card', linestyle='dotted')
Instead of random jitter, the lines can be offset just a little bit, creating a layered appearance:
import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy
grid = list(range(10))
graphs = [[1, 1, 1, 4, 4, 4, 3, 5, 6, 0],
[1, 1, 1, 5, 5, 5, 3, 5, 6, 0],
[1, 1, 1, 0, 0, 3, 3, 2, 4, 0],
[1, 2, 4, 4, 3, 2, 3, 2, 4, 0],
[1, 2, 3, 3, 4, 4, 3, 2, 6, 0],
[1, 1, 3, 3, 0, 3, 3, 5, 4, 3]]
fig, ax = plt.subplots()
lw = 1
for gg, graph in enumerate(graphs):
trans_offset = offset_copy(ax.transData, fig=fig, x=lw * gg, y=lw * gg, units='dots')
ax.plot(grid, graph, lw=lw, transform=trans_offset, label='g' + str(gg))
ax.legend(loc='upper left', bbox_to_anchor=(1.01, 1.01))
# manually set the axes limits, because the transform doesn't set them automatically
ax.set_xlim(grid[0] - .5, grid[-1] + .5)
ax.set_ylim(min([min(g) for g in graphs]) - .5, max([max(g) for g in graphs]) + .5)
plt.tight_layout()
plt.show()

Change position of bars of a Pandas histogram

I'm plotting several histograms using Pandas hist method.
%matplotlib inline
import pandas as pd
import numpy as np
d = {"columns":["a","b","c","d","e"],"index":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499],"data":[[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0],[0,0,0,-2,0],[0,0,4,0,-2],[3,1,0,-1,-2],[1,2,0,-1,-2],[1,0,0,-1,-2],[1,2,2,0,0],[-1,2,0,-1,1],[-1,0,0,-1,0],[-1,2,0,-1,-1],[3,0,1,-1,-1],[-2,0,-1,0,1],[-1,1,0,1,-2],[0,0,0,0,-2],[-1,2,0,-1,0],[0,0,-1,-2,0]]}
df = pd.DataFrame(d['data'], columns=d['columns'], index=d['index'])
bins = np.arange(-5, 5+1, 0.5)
_ = df.hist(figsize=(12, 10), bins=bins)
I'm getting the following histograms:
I'd like to have bars either centered on x-labels (-2, -1, 0, 1, 3) for "a" histogram or have bars at the left of x-labels
I'm looking at http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.hist.html but I can't find a solution.
In order to center the bars you can do
_ = df.hist(figsize=(12, 10), bins=bins, align='left')

How to plot pseudo-3d bar chart in matplotlib?

I'd like to prepare some statistics for my boss. The flat style of matplotlib bar chart would make them look cheap for those used to Excel charts, although for clarity, using styles like this probably should be avoided.
I'm not that far away, but I don't get how to give the right thickness of the bars:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
row = [0, 0, 0, 22, 0, 0, 4, 16, 2, 0, 4, 4, 12, 26]
length = len(row)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.arange(length)
y = np.zeros(14)
z = np.array(row)
width = 0.8
ax.bar3d(x, y, [0]*length, 0.5, 0.001, z)
ax.set_xticks(x + width/2)
ax.set_xticklabels(titles[2:], rotation=90)
ax.set_yticks(y)
ax.set_zlabel('count')
plt.show()
Result:
The thickness of the bars are set by the dx, dy arguments in ax.bar3d for which you have the values 0.5, 0.001. The issue, as I'm sure you noticed is that changing dy will change the length of the bar (in your case the untitled axis), but matplotlib helpfully rescales the y axis so the data fills it. This makes it look strange (I am assuming this is the problem, sorry if it isn't).
To remedy this you could set the y limits using ax.set_ylim(0, 0.002) (basically your y values go from 0->0.001). If you change either dy or the value of y given to bar3d which is currently 0, then you will need to update the limits accordingly.
Example:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
row = [0, 0, 0, 22, 0, 0, 4, 16, 2, 0, 4, 4, 12, 26]
length = len(row)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.bar3d(range(length), [0]*length, [0]*length, 0.5, 0.001, row)
ax.set_ylim(-0.005, 0.005)
plt.show()

Categories