How to set up a detailed heat map [duplicate] - python

This question already has answers here:
Change color according to conditions for seaborn heatmaps
(1 answer)
Changing annotation text color in Seaborn heat map
(1 answer)
How to visualize a list of strings on a colorbar in matplotlib
(1 answer)
Masking annotations in seaborn heatmap
(1 answer)
Change certain squares in a seaborn heat map
(2 answers)
Closed 8 months ago.
I'm currently working on a heat map produced by the following data.
df = pd.DataFrame(
data = {
'Set_A' : [91, 91, 91, 90, 91, 91, 91],
'Set_B' : [91, 92, 91, 89, 91, 91, 91],
'Set_C' : [89, 90, 89, 88, 90, 89, 89],
'model' : ['SVM', 'RF', 'LR', 'KNN', 'NB', 'MLP', 'LGB'],
}
)
df = df.set_index('model')
sns.heatmap(df, cmap='Reds', annot=True, vmin=85, vmax=95, annot_kws={'color':'black'}, linewidths=.5);
I have two questions.
How can I change the color of the text in the heat map to white for 91 and above and black for 90 and below?
Currently, the colorbar is 86 to 94. I would like to change this to show 85 to 95.

Related

Pie chart, how to put percentages next to graph? [duplicate]

This question already has answers here:
matplotlib percent label position in pie chart
(1 answer)
How do I use matplotlib autopct?
(7 answers)
How to avoid overlapping of labels & autopct in a matplotlib pie chart?
(4 answers)
Closed 1 year ago.
I was trying to create a pie chart with percentages next to the graph. The data that i have is the following.
users = [80, 40, 1000, 300, 50, 80, 10]
os = ['MacOS', 'Chrome', 'Windows', 'Linux', 'Devian', 'Ubuntu', 'Arch Linux']
And i´m trying to get something like this.
Try setting autopct to what you need:
plt.pie(users,
labels=os,
explode=[0, 0, 0.05, 0, 0, 0, 0],
pctdistance = 1.2,
labeldistance = 1.4,
autopct=lambda x: f'{x:.1f}%\n({(x/100)*sum(users):.0f} users)',
textprops={"family": "Arial", "size": 12},
radius = 2,
colors = ["#9BC2E6", "#FF6600", "#F4B084", "#00B050", "#C6E0B4", "#8633FF", "#CCCCFF"]
)
plt.legend(loc="best", bbox_to_anchor=(2.5,0), title="Operating systems")
Output:
Try using plotly.express:
import plotly.express as px
users = [80, 40, 1000, 300, 50, 80, 10]
os = ['MacOS', 'Chrome', 'Windows', 'Linux', 'Devian', 'Ubuntu', 'Arch Linux']
fig = px.pie(values=users, names=os,
color_discrete_sequence=px.colors.sequential.RdBu)
fig.update_traces(textposition='outside',
textinfo='percent+label+value',
marker=dict(line=dict(color='#FFFFFF', width=2)),
textfont_size=12)
fig.show()
The result is quite nice:

X-ticks values consistent with bars [duplicate]

This question already has answers here:
Aligning rotated xticklabels with their respective xticks
(5 answers)
Closed 1 year ago.
Could someone please help me to set my x-ticks with bars. The bars are not consistent with xtick time values as you can see in the image. I have printed my data values of g01, g02 below and code as well. I have tried this solution Python MatplotLib plot x-axis with first x-axis value labeled as 1 (instead of 0), plt.xticks(np.arange(len(g01)), np.arange(1, len(g01)+1)) although then bars are consistent with x-ticks but it changes to numbers 1 to 28. I want time period like in my image.
g01 = ['2021-02-01 05:00:31', '2021-02-02 00:01:04', '2021-02-03 00:05:09', '2021-02-04 00:05:15', '2021-02-05 00:03:14', '2021-02-06 00:00:25', '2021-02-07 00:04:09', '2021-02-08 00:04:35', '2021-02-09 00:00:00', '2021-02-10 00:02:00', '2021-02-11 00:01:28', '2021-02-12 00:06:31', '2021-02-13 00:00:30', '2021-02-14 00:03:30', '2021-02-15 00:05:20', '2021-02-16 00:00:13', '2021-02-17 00:00:21', '2021-02-18 00:08:02', '2021-02-19 00:00:31', '2021-02-20 00:00:04', '2021-02-21 00:05:05', '2021-02-22 00:02:18', '2021-02-23 00:00:10', '2021-02-24 00:00:38', '2021-02-25 00:00:47', '2021-02-26 00:00:17', '2021-02-27 00:00:28', '2021-02-28 00:03:00']
g02 = [164, 158, 180, 200, 177, 112, 97, 237, 95, 178, 163, 78, 67, 65, 134, 93, 220, 74, 131, 172, 77, 102, 208, 109, 113, 208, 110, 101]
fig = plt.figure()
fig, ax1 = plt.subplots(1,1)
plt.yscale("log")
barlist1=ax1.bar(g01,g02)
for i in range(21):
barlist1[i].set_color('pink')
degrees = 70
plt.xticks(rotation=degrees)
plt.xlabel('period', fontsize=14, fontweight="bold")
plt.ylabel('rating values', fontsize=10, fontweight="bold")
While the linked duplicate does improve the alignment with ha='right', the labels will still be slightly off.
First note that the ticks/labels are correctly mapped, which you can see by using rotation=90 (left subplot):
plt.xticks(rotation=90)
If you use rotation=70 with ha='right', notice that the labels are still slightly shifted. This is because matplotlib uses the text's bounding box for alignment, not the text itself (center subplot):
plt.xticks(rotation=70, ha='right')
To tweak the labels more precisely, add a ScaledTranslation transform (right subplot):
from matplotlib.transforms import ScaledTranslation
offset = ScaledTranslation(xt=0.075, yt=0, scale_trans=fig.dpi_scale_trans)
for label in ax1.xaxis.get_majorticklabels():
label.set_transform(label.get_transform() + offset)

plotly column with vertical border and color for specific column

I am looking for a solution to set a vertical border and color for a specific column(s). for this example the column "Scores".
import plotly.graph_objects as go
import plotly
fig = go.Figure(data=[go.Table(
header=dict(values=['<b>Values', '<b>Scores', 'column'],
line_color='darkslategray',
#fill_color='lightskyblue',
align='center'),
cells=dict(values=[[100, 100, 100, 300], # 1st column
[90, 90, 90, 270],
[90, 90, 90, 270]], # 2nd column
line_color='darkslategray',
#fill_color='lightcyan',
align='center'))
])
fig.update_layout(width=250, height=130)
fig.update_layout(margin=dict(l=10, r=10, t=10, b=10))
fig.show()
the perfect solution I expect looks like the table (created with excel). if somebody only know how to color the column this also would help. Thanks!
As far as I know, you cannot change the color of individual ruled lines. The only settings for lines are line width and color. The color for each cell can be specified individually by column or by an array corresponding to the cell.
import plotly.graph_objects as go
import plotly
fig = go.Figure(data=[go.Table(
header=dict(values=['<b>Values', '<b>Scores', 'column'],
line_color=['white','mediumpurple','white'],
fill_color=['white','mediumpurple','white'],
align='center'),
cells=dict(values=[[100, 100, 100, 300], # 1st column
[90, 90, 90, 270],
[90, 90, 90, 270]], # 2nd column
line_color=['white','mediumpurple','white'],
fill_color=['white','mediumpurple','white'],
align='center'))
])
fig.update_layout(width=250, height=130)
fig.update_layout(margin=dict(l=10, r=10, t=10, b=10))
fig.show()

Matplotlib blank space with no color when use fill_between with where option

Update:
I slice days into 100 points then interpolate the corresponding value of min_temp and max_temp, the result become better, but still some area have no color, how to modify it?
days_vals=numpy.linspace(1,10,100)
min_interp=numpy.interp(days_vals,days,min_temp)
max_interp=numpy.interp(days_vals,days,max_temp)
plt.xticks(days)
plt.plot(days_vals,min_interp,c='b',marker='o')
plt.plot(days_vals,max_interp,c='g',marker='o')
plt.fill_between(days_vals,min_interp,max_interp,where=[i>35 for i in min_interp],
facecolor='lightgreen',alpha=0.7,interpolate=False)
plt.fill_between(days_vals,min_interp,max_interp,where=[i<=35 for i in min_interp],
facecolor='lightpink',alpha=0.7,interpolate=False)
==========================================================================
I am using fill_between with where option to fill the color, min_temp > 35 fill green and min_temp <= 35 fill pink, but see the result is not as my expected
there are so many blank area with no color.
I search one question somelike my issue link
it solution is to add additional data-points to the series that that lie on the axis, but it not fix my issue
How can i modify my codes to make the color continuous with no blank space?
here's the codes:
from matplotlib import pyplot as plt
days=range(1,11)
max_temp=[37, 35, 42, 36, 39, 56, 50, 45, 41, 39]
min_temp=[32, 30, 37, 20, 34, 40, 37, 38, 32, 30]
fig=plt.figure(figsize=(10,8))
font={'weight':'normal',
'color':'cyan',
'fontsize':24,
}
plt.title('Weather 2014',fontdict=font)
plt.xlabel('Month',fontdict=font)
plt.ylabel('Temperature',fontdict=font)
plt.title('Weather 2014',fontdict=font)
plt.xlabel('Month',fontdict=font)
plt.ylabel('Temperature',fontdict=font)
plt.xticks(days)
plt.plot(days,max_temp,marker='o',mfc='red',mec='None',markersize=3,label='Max Temp')
plt.plot(days,min_temp,marker='o',mfc='g',mec='None',markersize=3,label='Min Temp')
'''add additional data points'''
eta=1e-6
plt.fill_between(days,min_temp,max_temp,where=[i+eta>35 for i in min_temp],
facecolor='lightgreen',alpha=0.7)
plt.fill_between(days,min_temp,max_temp,where=[i-eta<=35 for i in min_temp],
facecolor='lightpink',alpha=0.7)
plt.legend(loc='upper left',bbox_to_anchor=(1,1))
fig.autofmt_xdate()
plt.grid(True)
plt.show()

Conditionally change background color of specific cells

I have a DataFrame and I can save it as a png file. But now I want to change the background color of specific cells who meet a certain condition.
Conditions:
Numbers who are 80 or higher must get a green background.
Numbers below 80 must get a red background.
All column names and index cells need a black background with a white text color.
The following posts came close to what I want but didn't provided with the answer I needed.
Post 1
Post 2
My code:
import matplotlib.pyplot as plt
from pandas.tools.plotting import table
import pandas as pd
#My dataframe
df = pd.DataFrame({
'Weeks' : [201605, 201606, 201607, 201608],
'Computer1' : [50, 77, 96, 100],
'Computer2' : [50, 79, 100, 80],
'Laptop1' : [75, 77, 96, 95],
'Laptop2' : [86, 77, 96, 40],
'Phone' : [99, 99, 44, 85],
'Phone2' : [93, 77, 96, 25],
'Phone3' : [94, 91, 96, 33]
})
df2 = df.set_index('Weeks') #Makes the column 'Weeks' the index.
#Make a png file out of an dataframe.
plt.figure(figsize=(9,3))
ax = plt.subplot(211, frame_on=False) # no visible frame
ax.xaxis.set_visible(False) # hide the x axis
ax.yaxis.set_visible(False) # hide the y axis
table(ax, df2, rowLabels=df2.index, colLabels=df2.columns, loc='center', cellColours=None)
plt.savefig('mytable.png') #save it as an png.
This is how it currently looks:
This is how I want it to look
you can do something like this:
colors = df2.applymap(lambda x: 'green' if x>= 80 else 'red').reset_index().drop(['Weeks'], axis=1)
tbl = table(ax, df2, loc='center',
cellColours=colors.as_matrix(),
colColours=['black']*len(colors.columns),
rowColours=['black']*len(colors))
Setting index's color:
[tbl._cells[row, -1]._text.set_color('white') for row in range(1, len(colors)+1)]
setting header's colors:
[tbl._cells[0, col]._text.set_color('white') for col in range(len(colors.columns))]
plt.show()
Code (complete):
import matplotlib.pyplot as plt
from pandas.tools.plotting import table
import pandas as pd
#My dataframe
df = pd.DataFrame({
'Weeks' : [201605, 201606, 201607, 201608],
'Computer1' : [50, 77, 96, 100],
'Computer2' : [50, 79, 100, 80],
'Laptop1' : [75, 77, 96, 95],
'Laptop2' : [86, 77, 96, 40],
'Phone' : [99, 99, 44, 85],
'Phone2' : [93, 77, 96, 25],
'Phone3' : [94, 91, 96, 33]
})
df2 = df.set_index('Weeks') #Makes the column 'Weeks' the index.
colors = df2.applymap(lambda x: 'green' if x>= 80 else 'red') \
.reset_index().drop(['Weeks'], axis=1)
#print(colors)
plt.figure(figsize=(10,5))
ax = plt.subplot(2, 1, 1, frame_on=True) # no visible frame
#ax.xaxis.set_visible(False) # hide the x axis
#ax.yaxis.set_visible(False) # hide the y axis
# hide all axises
ax.axis('off')
# http://matplotlib.org/api/pyplot_api.html?highlight=table#matplotlib.pyplot.table
tbl = table(ax, df2,
loc='center',
cellLoc='center',
cellColours=colors.as_matrix(),
colColours=['black']*len(colors.columns),
rowColours=['black']*len(colors),
#fontsize=14
)
# set color for index (X, -1) and headers (0, X)
for key, cell in tbl.get_celld().items():
if key[1] == -1 or key[0] == 0:
cell._text.set_color('white')
# remove grid lines
cell.set_linewidth(0)
# refresh table
plt.show()
# save it as an png.
plt.savefig('mytable.png')

Categories