How do I set the width of the rowLabels column on matplotlib? - python

It seems code below should set the width of the column containing the row labels. Yet it only sets the other columns.
I've also tried passing a colWidths argument but the result is the same.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.axis('tight')
ax.axis('off')
colLabels = ['ColA', 'ColB', 'ColC', 'ColD', 'ColE']
rowLabels = ['Row1', 'Row2', 'Row3', 'Row4']
dados = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
]
table = ax.table(
cellText=dados, loc='center',
colLabels=colLabels,
rowLabels=rowLabels,
# `colWidths=[0.15, 0.15, 0.15, 0.15, 0.15, 0.15, ],` # <- same result
)
for cell in table.get_celld().values():
cell.set_width(.15)
print(cell.get_text().get_text()) # shows that the column is iterated through
plt.show()

The column containing the "Row" titles tries to automatically set the width. To stop this happening you can reset table._autoColumns to an empty list, e.g.,:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.axis('tight')
ax.axis('off')
colLabels = ['ColA', 'ColB', 'ColC', 'ColD', 'ColE']
rowLabels = ['Row1', 'Row2', 'Row3', 'Row4']
dados = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
]
table = ax.table(
cellText=dados, loc='center',
colLabels=colLabels,
rowLabels=rowLabels,
# `colWidths=[0.15, 0.15, 0.15, 0.15, 0.15, 0.15, ],` # <- same result
)
table._autoColumns = [] # empty the _autoColumns
for cell in table.get_celld().values():
cell.set_width(.15)
print(cell.get_text().get_text()) # shows that the column is iterated through
plt.show()

Related

Heatmap with different colors for each row [duplicate]

This question already has answers here:
Annotated heatmap with multiple color schemes
(2 answers)
How to create a heat-map with multiple colormaps?
(2 answers)
Heatmap with multiple colormaps by column
(2 answers)
Closed last month.
I am trying to build a heatmap with seaborn that each row of the 'table' get a different color range. Example:
A: yellow
B: blue
C: green
D: red
must be in the same table for comparing the own row along the year and different rows in the same month. Is my question clear, thanks so much?
I only could plot the heatmap comparing all the table:
d = {'jan': [44, 2, 3, 4],
'feb': [33, 4, 6, 8],
'mar': [50, 10, 15, 20],
'abr': [11, 12, 13, 14],
'mai': [3, 40, 6, 60],
'jun': [40, 8, 12, 16]}
idx = ['A', 'B', 'C', 'D']
df = pd.DataFrame(d, index = idx)
sns.heatmap(df, annot = True, cmap = 'Blues')
plt.yticks(rotation = 0)
That is what i trying to plot. Made with google sheets:
I suggest you to do one plot per line and put them into a plt subplot:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
d = {'jan': [44, 2, 3, 4], 'feb': [33, 4, 6, 8], 'mar': [50, 10, 15, 20], 'abr': [11, 12, 13, 14], 'mai': [3, 40, 6, 60], 'jun': [40, 8, 12, 16]}
idx = ['A', 'B', 'C', 'D']
df = pd.DataFrame(d, index = idx)
cm = ['Blues', 'Reds', 'Greens', 'Purples']
f, axs = plt.subplots(4, 1, gridspec_kw={'hspace': 0})
counter = 0
for index, row in df.iterrows():
sns.heatmap(np.array([row.values]), yticklabels=[idx[counter]], xticklabels=df.columns, annot=True, fmt='.2f', ax=axs[counter], cmap=cm[counter], cbar=False)
counter += 1
plt.show()
Output :

Python - Bland-Altman Plot with Text Customization

I am trying to Create the Bland-Altman Plot with the text having on the left side of the plot instead of having it as the default configuration on the right hand side
This is my code
import pandas as pd
df = pd.DataFrame({'A': [5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9,
10, 11, 13, 14, 14, 15, 18, 22, 25],
'B': [4, 4, 5, 5, 5, 7, 8, 6, 9, 7, 7, 11,
13, 13, 12, 13, 14, 19, 19, 24]})
import statsmodels.api as sm
import matplotlib.pyplot as plt
#create Bland-Altman plot
f, ax = plt.subplots(1, figsize = (8,5))
sm.graphics.mean_diff_plot(df.A, df.B, ax = ax)
#display Bland-Altman plot
plt.show()
So I want to have the "mean", the "SD+" and the "SD-" on the left side of the X-axis, not on the right.
thanks for your help or any suggestions!
I don't know, but I can use pyplot so:
mean_diff = (df.A-df.B).mean()
diff_range = (df.A-df.B).std()*1.96
plt.figure(figsize = (9,6))
plt.scatter(df.A, df.A-df.B, alpha=.5)
plt.hlines(mean_diff, df.A.min()-2, df.A.max()+2, color="k", linewidth=1)
plt.text(
df.A.min()-1, mean_diff+.05*diff_range, "mean diff: %.2f"%mean_diff,
fontsize=13,
)
plt.hlines(
[mean_diff+diff_range, mean_diff-diff_range],
df.A.min()-2, df.A.max()+2, color="k", linewidth=1,
linestyle="--"
)
plt.text(
df.A.min()-1, mean_diff+diff_range+.05*diff_range,
"+SD1.96: %.2f"%(mean_diff+diff_range),
fontsize=13,
)
plt.text(
df.A.min()-1, mean_diff-diff_range+.05*diff_range,
"-SD1.96: %.2f"%(mean_diff-diff_range),
fontsize=13,
)
plt.xlim(df.A.min()-2, df.A.max()+2)
plt.ylim(mean_diff-diff_range*1.5, mean_diff+diff_range*1.5)
plt.xlabel("Means", fontsize=15)
plt.ylabel("Difference", fontsize=15)
plt.show()
result:

How can I fix this error TypeError: colormaps() takes 0 positional arguments but 1 was given

Good afternoon, I am trying to replicate the Discrete distribution as horizontal bar chart of matplotlib documentation.
I copy and paste the code from matplotlib but a TypeError: colormaps() takes 0 positional arguments but 1 was given
How may i fix it?
import numpy as np
import matplotlib.pyplot as plt
category_names = ['Strongly disagree', 'Disagree',
'Neither agree nor disagree', 'Agree', 'Strongly agree']
results = {
'Question 1': [10, 15, 17, 32, 26],
'Question 2': [26, 22, 29, 10, 13],
'Question 3': [35, 37, 7, 2, 19],
'Question 4': [32, 11, 9, 15, 33],
'Question 5': [21, 29, 5, 5, 40],
'Question 6': [8, 19, 5, 30, 38]
}
def survey(results, category_names):
"""
Parameters
----------
results : dict
A mapping from question labels to a list of answers per category.
It is assumed all lists contain the same number of entries and that
it matches the length of *category_names*.
category_names : list of str
The category labels.
"""
labels = list(results.keys())
data = np.array(list(results.values()))
data_cum = data.cumsum(axis=1)
category_colors = plt.colormaps('RdYlGn')(np.linspace(0.15, 0.85, data.shape[1]))
fig, ax = plt.subplots(figsize=(9.2, 5))
ax.invert_yaxis()
ax.xaxis.set_visible(False)
ax.set_xlim(0, np.sum(data, axis=1).max())
for i, (colname, color) in enumerate(zip(category_names, category_colors)):
widths = data[:, i]
starts = data_cum[:, i] - widths
rects = ax.barh(labels, widths, left=starts, height=0.5,
label=colname, color=color)
r, g, b, _ = color
text_color = 'white' if r * g * b < 0.5 else 'darkgrey'
ax.bar_label(rects, label_type='center', color=text_color)
ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),
loc='lower left', fontsize='small')
return fig, ax
survey(results, category_names)
plt.show()
And the error is
line 38, in survey
category_colors = plt.colormaps('RdYlGn')(np.linspace(0.15, 0.85, data.shape[1]))
TypeError: colormaps() takes 0 positional arguments but 1 was given

Python: how to divide particles into different clusters according to their coordinates?

Firstly, I generate 20 pairs of random numbers and use them as 2D spatial positions of 20 particles.
import numpy as np
positions = np.random.rand(20,2)
Positions is shown as follows
array([[0.96124789, 0.52413156],
[0.5186589 , 0.4300743 ],
[0.63357087, 0.70130091],
[0.8213765 , 0.29515393],
[0.68616945, 0.02020544],
[0.71924115, 0.71630689],
[0.92340942, 0.56007463],
[0.17322848, 0.2455891 ],
[0.3993029 , 0.53287478],
[0.15887798, 0.60968053],
[0.45877831, 0.88163765],
[0.04565275, 0.76557075],
[0.73800541, 0.71257644],
[0.02784201, 0.10035848],
[0.83830731, 0.66442518],
[0.95518272, 0.37313694],
[0.14761192, 0.8255784 ],
[0.83576694, 0.18367566],
[0.79187776, 0.52189936],
[0.97585451, 0.97077229]])
What I want to do is classifying these particles into different clusters according to their spatial distribution. For this purpose, I build one K-d tree by importing scipy.spatial.cKDTree and find all pairs of points in this tree whose distance is at most 0.2 by using method query_pairs.
from scipy.spatial import cKDTree as kdtree
tree=kdtree(positions)
pairs= tree.query_pairs(r=0.2, output_type="ndarray")
pairs[np.argsort(pairs[:,0])] # Sorting pairs along axis=0
The output of the code snippet above is shown as follows.
array([[ 0, 6],
[ 0, 15],
[ 0, 18],
[ 0, 14],
[ 1, 8],
[ 2, 5],
[ 2, 12],
[ 3, 17],
[ 3, 15],
[ 5, 12],
[ 5, 14],
[ 6, 18],
[ 6, 14],
[ 6, 15],
[ 9, 11],
[11, 16],
[12, 18],
[12, 14],
[14, 18]], dtype=int64)
According to pairs, We can classify these particles into 3 clusters visually, i.e.
a). (0, 3, 5, 6, 12, 14, 15, 17, 18)
b). (1,8)
c). (9, 11, 16)
So my question is that how to do this classification by Python itself?
You could try KMeans from sklearn:
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
import numpy as np
positions = np.array([[0.96124789, 0.52413156], [0.5186589, 0.4300743], [0.63357087, 0.70130091], [0.8213765, 0.29515393], [0.68616945, 0.02020544], [0.71924115, 0.71630689], [0.92340942, 0.56007463], [0.17322848, 0.2455891], [0.3993029, 0.53287478], [0.15887798, 0.60968053], [0.45877831, 0.88163765], [0.04565275, 0.76557075], [0.73800541, 0.71257644], [0.02784201, 0.10035848], [0.83830731, 0.66442518], [0.95518272, 0.37313694], [0.14761192, 0.8255784], [0.83576694, 0.18367566], [0.79187776, 0.52189936], [0.97585451, 0.97077229]])
kmeans = KMeans(n_clusters=3).fit(positions)
fig, ax = plt.subplots()
for i, (color, center) in enumerate(zip(['crimson', 'dodgerblue', 'limegreen'], kmeans.cluster_centers_)):
ax.scatter(*positions[kmeans.labels_ == i].T, color=color, label=f'Cluster {i}')
ax.scatter(*center, ec=color, fc='None', s=100)
ax.set_aspect('equal')
rnd = np.random.rand(10000, 2)
rnd_labels = kmeans.predict(rnd)
for i, (color) in enumerate(['crimson', 'dodgerblue', 'limegreen']):
ax.scatter(*rnd[rnd_labels == i].T, ec='none', fc=color, marker='.', s=3)
ax.legend(bbox_to_anchor=(1.02, 0.95), loc='upper left')
plt.tight_layout()
plt.show()

Creating multiple images of heatmap using pandas, seaborn?

Currently, I am trying to output image outputs for my data.
My original source is like this:
total_dict = {"A" : {"A1" : [1, 2, 3, 4, 5], "A2" : [2, 3, 4, 5, 6]}, "B" : {"B1" : [11, 22, 13, 34, 5], "B2" : [12, 31, 42, 52, 16]},"C" : {"C1" : [12, 22, 33, 4, 5], "C2" : [42, 33, 42, 15, 6]}, "D" : {"D1" : [1, 23, 35, 4, 5], "D2" : [21, 23, 34, 5, 6]}}
Now, I am trying to create 4 heat maps for each sub-library: A, B, C and D.
My program is:
import pandas as pd
import seaborn as sns
for sub in total_dict:
df = pd.DataFrame(total_dict[sub])
image = sns.heatmap(df, cmap="YlGnBu", linewidths = 0.1, vmax = 100)
print (image)
However, it does not print out 4 separate images as I expected. The final result is:
heatmap_result
Could you please suggest me any method that I can use to get my expected 4 separate outputs as well as be able to save them in 4 separate files.
Thanks for your help.
You can define a new figure, plot the heat-map, and save the figure.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
for index, sub in enumerate(total_dict):
df = pd.DataFrame(total_dict[sub])
# create a new figure
fig = plt.figure()
image = sns.heatmap(df, cmap="YlGnBu", linewidths = 0.1, vmax = 100)
fig_name = 'test_%s.png' %(index)
fig.savefig(fig_name)

Categories