Define title to a matplotlib table - python

I have a table generated by matplotlib, and I want to insert a title for it. Do anyone know how to do it?
ax = fig.add_subplot(111)
fig = plt.figure(constrained_layout=True)
spec2 = gridspec.GridSpec(ncols=2, nrows=3, figure=fig )
ax1 = fig.add_subplot(spec2[0, 0])
ax2 = fig.add_subplot(spec2[0, 1])
ax1.axis('off')
ax2.axis('off')
table_data=[
["Ni_Tot ", "NN", "2.5%" , round(df.NN_Ni_Tot.quantile(0.025),3)],
["N. of Samples", count, "5%" , round(df.NN_Ni_Tot.quantile(0.05),3)],
["Minimum", round(min(df['NN_Ni_Tot'].apply(pd.to_numeric)),3), "25%" , round(df.NN_Ni_Tot.quantile(0.25),3)],
["Maximum", round(max(df['NN_Ni_Tot'].apply(pd.to_numeric)),3), "Median", round(df.NN_Ni_Tot.quantile(0.5),3)],
["Average", round(statistics.mean(df['NN_Ni_Tot'].apply(pd.to_numeric)),3),"75%", round(df.NN_Ni_Tot.quantile(0.75),3)],
["Variance", round(df['NN_Ni_Tot'].var(),2), "95%", round(df.NN_Ni_Tot.quantile(0.95),3)],
["Std Deviation", round(df['NN_Ni_Tot'].std(),2),"97.5%", round(df.NN_Ni_Tot.quantile(0.975),3)],]
table = ax1.table(cellText=table_data, loc='center', cellLoc='center')
table.set_fontsize(14)
table.scale(1.5,1.4)
https://i.stack.imgur.com/P27Vu.png

ax.set_title("Your title")
Relevant documentation

ax1.set_title("Your title")
The code line above worked, but the title was positioned in the middle of the table, overlapping the data. So I had to ajust it manually
ax1.set_title("NN_NI", fontsize=8, y=1.8, pad=-14)

Related

plotly bar chart annotate text cut-off

The annotation text at the last bar has been cut off somehow.
What's proper way to fix it?
#!/usr/bin/env python3
import pandas as pd
import re
import datetime
import os
import plotly.graph_objects as go
import numpy as np
import math
import datetime
def save_fig(fig,pngname):
fig.write_image(pngname,format="png", width=800, height=400, scale=1)
print("[[%s]]"%pngname)
return
def plot_bars(df,pngname):
colors = ['#5891ad','#004561','#ff6f31','#1c7685','#0f45a8','#4cdc8b','#0097a7']
fig = go.Figure()
traces = []
xname = df.columns[0]
for i,yname in enumerate(df.columns):
if i == 0: continue
trace1 = go.Bar(
name=yname,
x=df[xname],y=df[yname],meta=df.index,
#texttemplate="%{%.1f}",
text=df[yname],
textposition="outside",
textangle=-25,
textfont_color="black",
marker_color=colors[i-1],
hovertemplate='<br>'.join([
'id:%{meta}',
'ts: %{x|%H:%M:%S}',
'val: %{y:.1f}',
]),
)
traces.append(trace1)
fig.add_traces(traces)
#d0 = df[xname][0].replace(minute=0, second=0) - datetime.timedelta(hours=1)
fig.update_layout(
margin=dict(l=10,t=40,r=10,b=40),
plot_bgcolor='#ffffff',#'rgb(12,163,135)',
paper_bgcolor='#ffffff',
title="Boot progress",
xaxis_title="Keypoints",
yaxis_title="Timestamp(secs)",
title_x=0.5,
barmode='group',
bargap=0.05,
bargroupgap=0.0,
legend=dict(x=.02,y=1),
xaxis=dict(
#tick0 = d0,
#dtick=7200000,
tickangle=-25,
#tickmode='array',
#tickvals = xvals,
#ticktext= xtexts,
#tickformat = '%m-%d %H:%M:%S',#datetime format
showline=True,
linecolor='black',
color='black',
linewidth=.5,
ticks='outside',
#mirror=True,
),
yaxis=dict(
dtick=10,
showline=True,
linecolor='black',
color='black',
linewidth=.5,
#tickvals = yvals,
#ticktext= ytexts,
showgrid=True,
gridcolor='#ececec',
gridwidth=.5,
griddash='solid',#'dot',
zeroline=True,
zerolinecolor='grey',
zerolinewidth=.5,
showticklabels=True,
#mirror=True,
),
)
anns = []
#anns = add_line(fig,anns,x0,y0,x1,y1,text=None)
#add_anns(fig,anns)
save_fig(fig,pngname)
return
def main():
data = [
["A",10,12],
["B",12,11],
["C",14,13],
["D",16,15],
["E",18,19]
]
df = pd.DataFrame(data,columns=["Kepoint","g1","g2"])
plot_bars(df,"demo.png")
return
main()
output png:
Although you could hardcode the range of the y-axes to have a larger maximum value, it's better to use a more flexible solution. Plotly's default behavior is to set the y-range by calculating [y_min-padding, y_max+padding] where the padding = (y_max-y_min)/16.
So we can include a padding multipler to make the padding a bit larger, and specify the new range by passing the argument range=[y_min-y_padding, y_max+y_padding] to yaxis:
def plot_bars(df,pngname):
colors = ['#5891ad','#004561','#ff6f31','#1c7685','#0f45a8','#4cdc8b','#0097a7']
fig = go.Figure()
traces = []
xname = df.columns[0]
for i,yname in enumerate(df.columns):
if i == 0: continue
trace1 = go.Bar(
name=yname,
x=df[xname],y=df[yname],meta=df.index,
#texttemplate="%{%.1f}",
text=df[yname],
textposition="outside",
textangle=-25,
textfont_color="black",
marker_color=colors[i-1],
hovertemplate='<br>'.join([
'id:%{meta}',
'ts: %{x|%H:%M:%S}',
'val: %{y:.1f}',
]),
)
traces.append(trace1)
fig.add_traces(traces)
#d0 = df[xname][0].replace(minute=0, second=0) - datetime.timedelta(hours=1)
y_min = df[["g1","g2"]].min().min()
y_max = df[["g1","g2"]].max().max()
padding_multiplier = 1.25
y_padding = padding_multiplier*(y_max-y_min)/16
fig.update_layout(
margin=dict(l=10,t=40,r=10,b=40),
plot_bgcolor='#ffffff',#'rgb(12,163,135)',
paper_bgcolor='#ffffff',
title="Boot progress",
xaxis_title="Keypoints",
yaxis_title="Timestamp(secs)",
title_x=0.5,
barmode='group',
bargap=0.05,
bargroupgap=0.0,
legend=dict(x=.02,y=1),
xaxis=dict(
#tick0 = d0,
#dtick=7200000,
tickangle=-25,
#tickmode='array',
#tickvals = xvals,
#ticktext= xtexts,
#tickformat = '%m-%d %H:%M:%S',#datetime format
showline=True,
linecolor='black',
color='black',
linewidth=.5,
ticks='outside',
#mirror=True,
),
yaxis=dict(
dtick=10,
range=[y_min-y_padding, y_max+y_padding],
showline=True,
linecolor='black',
color='black',
linewidth=.5,
#tickvals = yvals,
#ticktext= ytexts,
showgrid=True,
gridcolor='#ececec',
gridwidth=.5,
griddash='solid',#'dot',
zeroline=True,
zerolinecolor='grey',
zerolinewidth=.5,
showticklabels=True,
#mirror=True,
),
)
anns = []
#anns = add_line(fig,anns,x0,y0,x1,y1,text=None)
#add_anns(fig,anns)
save_fig(fig,pngname)
return

Hover for different items from legend in Bokeh multiline chart

How can I create a hoover for a Bokeh multiline graph where the hover shows data only for the current line?
Example:
I have line1 and line2.
When I hover over line1 I want to see:
Values: values
Line: name of the line
Here is my code:
graph:
fig2 = figure(x_range=x, y_range=[0, 1], plot_width=1500,
plot_height=600)
line1_2 = fig2.line(x, churn_40d_12m_all, color='blue', line_width=2)
circle1_2 = fig2.circle(x, churn_40d_12m_all, color='blue')
line2_2 = fig2.line(x, churn_40d_12m_b2b, color='brown', line_width=2)
circle2_2 = fig2.circle(x, churn_40d_12m_b2b, color='brown')
line3_2 = fig2.line(x, churn_40d_12m_b2c, color='green', line_width=2)
circle3_2 = fig2.circle(x, churn_40d_12m_b2c, color='green')
line4_2 = fig2.line(x, churn_40d_6m, color='red', line_width=2)
circle4_2 = fig2.circle(x, churn_40d_6m, color='red')
fig2.xaxis.axis_label = 'Month'
fig2.xaxis.major_label_orientation= math.pi/2
fig2.xaxis.axis_label_text_font_size = "20px"
fig2.yaxis.axis_label_text_font_size = "20px"
fig2.yaxis.axis_label = 'Values'
fig2.yaxis[0].formatter = NumeralTickFormatter(format="0.0%")
fig2.add_tools(hover)
fig2.add_layout(Legend(), 'right')
legend2 = Legend(items=[
("Line1", [line1_2, circle1_2]),
("Line2", [line2_2, circle2_2]),
("Line3", [line3_2, circle3_2]),
("Line4", [line4_2, circle4_2]),
], location="top_right")
fig2.add_layout(legend2, 'right')
legend2.click_policy = 'hide'
legend2.title="MultilineChart1"
legend2.title_text_font_size = "20px"
legend2.title_text_font_style = "bold"
legend2.label_text_font_size = "15px"
tab2 = Panel(child=fig2, title="MultiLineChart1")
Hover code:
hover = HoverTool(tooltips=[
('Values', '#y{0.00 %}'),
('Line', 'name of the current line')
])
Thank you!
So I managed to find a solution for this:
df = pd.DataFrame(dict(x=x, y1=churn_3d_12m_all, y2=churn_3d_6m))
source = ColumnDataSource(df)
p = figure(tooltips=[
('Вид чърн', '$name'),
('процент чърн', '$y{0.00 %}')
])
for name in ("y1", "y2"):
p.line("x", name, source=source, name=name)
output_file("fig1.html")
show(p)

How can my TimeSeries Plot starts at "00:00" and finish at "23:00" ? Without spaces on the sides

I need to plot without those spaces on the sides (left and right)
As I am a new user in Stack Overflow, I can't show an image here, the link is:
enter image description here
This is my code:
by_time_month = []
for i in range(12):
b_t_m = demand[f'2019-{i+1}'].groupby(demand[f'2019-{i+1}'].index.time).mean()
by_time_month.append(b_t_m)
i=i+1
hourly_ticks_3 = 3*60*60*np.arange(8)
months = ('Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre')
fig, ax = plt.subplots(nrows=6, ncols=2, figsize=(13, 22))
for by_month, ax, subtitle in zip(by_time_month, fig.get_axes(), months):
ax.plot(by_month, label='Demanda')
ax.set_xticks(hourly_ticks_3)
ax.set_title('Diagrama de Carga de ' + subtitle + ' 2019' + '\n-Promedio mensual-')
ax.set_xlabel('Hora del día')
ax.set_ylabel('Demanda [MW]')
ax.axvline("17:00", color="C1", linestyle="--", lw=1, alpha=0.8)
ax.axvline("23:00", color="C1", linestyle="--", lw=1, alpha=0.8)
ax.text("20:00", 0.15, 'Horas Punta', transform=ax.get_xaxis_transform(), bbox=dict(fc='none', ec='C1', boxstyle='round'), ha='center')
ax.grid(True, lw=0.8, alpha=0.5)
ax.legend()
plt.tight_layout()
I found the answer:
ax.set_xlim("00:00", "23:00")
I wasn't sure whether to delete this post or leave it posted here. It could help other people with the same "problem".

Encountering time out error in the middle of a matplotlib for loop

I have a code which will go through three dictionaries, and make some plots if the keys all match. I've been running into an odd issue due to the use of the matplotlib table.
When I first got this code to run, I had no issues finishing the whole loop. Now I am encountering a time out error by the second iteration
I tried moving the the table out of the for loop.
I added plt.close('all')
I also try importing matplotlib again at the end of the loop in hopes of resetting something in the backend.
for k, v in oct_dict.items():
for k2, v2 in stu_dict.items():
for k3, v3 in oct2_dict.items():
if k == k2 and k == k3:
with PdfPages('{}.pdf'.format(k)) as pdf:
#rc('font', **{'family': 'serif', 'serif': ['Computer Modern']})
#v = v[v['a_1920'] != 0]
rc('text', usetex=True)
fig = plt.figure(figsize = (8,10.5))
gs=GridSpec(2,2) # 2 rows, 3 columns
ax0 = fig.add_subplot(gs[0,0])
ax0.bar(x=np.arange(2), height = [float(v['a_1920'])*100, mean_a_1920*100], color = nice)
plt.xticks(np.arange(2), ['{}'.format(k), 'D75'])
for p in ax0.patches:
a =p.get_height()
ax0.annotate('{:0.2f}'.format(float(a)), (p.get_x()+.1, p.get_height() * .75), weight = 'bold')
ax1 = fig.add_subplot(gs[0,1])
c = str(len(v2['student_id']))
c2 = int(v['c_1920'])
props = dict(boxstyle='round', facecolor='white', alpha=0.0)
c3 = int(v['b_1920'])
# place a text box in upper left in axes coords
c4 = int(v['d_1920'])
ax1.text(0.0, 0.95, 'Number of Age : {}'.format(c3), transform=ax1.transAxes, fontsize=12,
verticalalignment='top')
ax1.text(0.0, 0.85, 'Number of Incomplete : {}'.format(c2), transform=ax1.transAxes, fontsize=12,
verticalalignment='top')
ax1.text(0.0, 0.75, 'Number of Invalid : {}'.format(c4), transform = ax1.transAxes, fontsize = 12,
verticalalignment = 'top' )
ax1.text(0.0, 0.65, 'Number of who will reach Age:\n{}'.format(c), transform=ax1.transAxes, fontsize=12,
verticalalignment='top' )
#ax1.table(cellLoc = 'center', cellText = [] , loc = 'upper center')
ax1.axis('off')
ax1.axis('tight')
#fig.suptitle('Monthly Summary', va = 'top', ha= 'center')
fig.text(0.3, 1, 'Monthly Summary '+ dt.date.today().strftime("%b %d, %Y"), fontsize=12, verticalalignment='top', bbox=props)
#plt.subplots_adjust(top = .75)
#plt.tight_layout()
#gs.constrained_layout()
#print(float(v3['inc']))
#print(float(v3['com']))
ax2 = fig.add_subplot(gs[1,0])
plt.sca(ax2)
p1 = plt.bar(np.arange(1), int(v3['com']), width=.25,color = 'b',label = 'Complete')
p2 = plt.bar(np.arange(1), int(v3['inc']), width = .25, bottom = int(v3['com']), color = 'r', label = 'Incomplete')
plt.legend()
for p in ax2.patches:
ax2.annotate((p.get_height()), (p.get_x()+.1, p.get_height() * .75), weight = 'bold')
ax2.set_xticks([])
# # #ax2.set_xlabel='Students Who Will Turn 15'
ax2.set_title('Students who will turn 15 later in the school year')
ax2.set_xticks([])
ax3 = fig.add_subplot(gs[1,1])
a = int(v3['com'])+int(v3['inc'])
ax3.axis('off')
plt.tight_layout()
pdf.savefig()
plt.close('all')
fig = plt.figure(figsize = (8,11.5))
gs=GridSpec(1,1)
axs = fig.add_subplot(gs[0])
cell_text = []
v2 = v2.drop(['Grand Total','birth_dte','loc'],axis = 1)
binarymap = {0:'No',1:'Yes'}
v2['Plan Not Complete'] = v2['Plan Not Complete'].map(binarymap)
v2['Plan Already Complete'] = v2['Plan Already Complete'].map(binarymap)
labels = [six column titles here]
for row in range(len(v2)):
try:
cell_text.append(v2.iloc[row])
except:
pass
table = axs.table(cellLoc = 'center', cellText = cell_text, colLabels = labels,
rowLoc = 'center', colLoc = 'center',loc = 'upper center',fontsize = 32)
table.set_fontsize(32)
table.scale(1, 1.5)
#axs.text(0.0,0.5,'For the column')
axs.axis('off')
pdf.savefig()
#plt.savefig('{}_list.pdf'.format(k))
plt.show()
plt.close('all')
import matplotlib.pyplot as plt
TimeoutError: Lock error: Matplotlib failed to acquire the following lock file:
C:\Users\myusername.matplotlib\tex.cache\23c95fa5c37310802233a994d78d178d.tex.matplotlib-lock
NOTE: If some of the key names dont match in this code it is on purpose, I had to change them up for this post since it is public. The error is thrown by the second iteration once the code reaches the axs.table line.
I got everything to run properly after using the conda command prompt to clean the environments
conda clean --all
Something that works but I would have liked to avoid was just removing the use of tex for this script. rc param tex set to False, code finished running pretty quickly as well

How to manually change the tick labels of the margin plots on a Seaborn jointplot

I am trying to use a log scale as the margin plots for my seaborn jointplot. I am usings set_xticks() and set_yticks(), but my changes do not appear. Here is my code below and the resulting graph:
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import seaborn as sns
import pandas as pd
tips = sns.load_dataset('tips')
female_waiters = tips[tips['sex']=='Female']
def graph_joint_histograms(df1):
g=sns.jointplot(x = 'total_bill',y = 'tip', data = tips, space = 0.3,ratio = 3)
g.ax_joint.cla()
g.ax_marg_x.cla()
g.ax_marg_y.cla()
for xlabel_i in g.ax_marg_x.get_xticklabels():
xlabel_i.set_visible(False)
for ylabel_i in g.ax_marg_y.get_yticklabels():
ylabel_i.set_visible(False)
x_labels = g.ax_joint.get_xticklabels()
x_labels[0].set_visible(False)
x_labels[-1].set_visible(False)
y_labels = g.ax_joint.get_yticklabels()
y_labels[0].set_visible(False)
y_labels[-1].set_visible(False)
g.ax_joint.set_xlim(0,200)
g.ax_marg_x.set_xlim(0,200)
g.ax_joint.scatter(x = df1['total_bill'],y = df1['tip'],data = df1,c = 'y',edgecolors= '#080808',zorder = 2)
g.ax_joint.scatter(x = tips['total_bill'],y = tips['tip'],data = tips, c= 'c',edgecolors= '#080808')
ax1 =g.ax_marg_x.get_axes()
ax2 = g.ax_marg_y.get_axes()
ax1.set_yscale('log')
ax2.set_xscale('log')
ax1.set_yscale('log')
ax2.set_xscale('log')
ax2.set_xlim(1e0, 1e4)
ax1.set_ylim(1e0, 1e3)
ax2.xaxis.set_ticks([1e0,1e1,1e2,1e3])
ax2.xaxis.set_ticklabels(("1","10","100","1000"), visible = True)
plt.setp(ax2.get_xticklabels(), visible = True)
colors = ['y','c']
ax1.hist([df1['total_bill'],tips['total_bill']],bins = 10, stacked=True,log = True,color = colors, ec='black')
ax2.hist([df1['tip'],tips['tip']],bins = 10,orientation = 'horizontal', stacked=True,log = True,color = colors, ec='black')
ax2.set_ylabel('')
Any ideas would be much appreciated.
Here is the resulting graph:
You should actually get an error from the line g.ax_marg_y.get_axes() since an axes does not have a get_axes() method.
Correcting for that
ax1 =g.ax_marg_x
ax2 = g.ax_marg_y
should give you the desired plot. The ticklabels for the log axis are unfortunately overwritten by the histogram's log=True argument. So you can either leave that out (since you already set the axes to log scale anyways) or you need to set the labels after calling hist.
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset('tips')
def graph_joint_histograms(tips):
g=sns.jointplot(x = 'total_bill',y = 'tip', data = tips, space = 0.3,ratio = 3)
g.ax_joint.cla()
g.ax_marg_x.cla()
g.ax_marg_y.cla()
for xlabel_i in g.ax_marg_x.get_xticklabels():
xlabel_i.set_visible(False)
for ylabel_i in g.ax_marg_y.get_yticklabels():
ylabel_i.set_visible(False)
x_labels = g.ax_joint.get_xticklabels()
x_labels[0].set_visible(False)
x_labels[-1].set_visible(False)
y_labels = g.ax_joint.get_yticklabels()
y_labels[0].set_visible(False)
y_labels[-1].set_visible(False)
g.ax_joint.set_xlim(0,200)
g.ax_marg_x.set_xlim(0,200)
g.ax_joint.scatter(x = tips['total_bill'],y = tips['tip'],data = tips,
c = 'y',edgecolors= '#080808',zorder = 2)
g.ax_joint.scatter(x = tips['total_bill'],y = tips['tip'],data = tips,
c= 'c',edgecolors= '#080808')
ax1 =g.ax_marg_x
ax2 = g.ax_marg_y
ax1.set_yscale('log')
ax2.set_xscale('log')
ax2.set_xlim(1e0, 1e4)
ax1.set_ylim(1e0, 1e3)
ax2.xaxis.set_ticks([1e0,1e1,1e2,1e3])
ax2.xaxis.set_ticklabels(("1","10","100","1000"), visible = True)
plt.setp(ax2.get_xticklabels(), visible = True)
colors = ['y','c']
ax1.hist([tips['total_bill'],tips['total_bill']],bins = 10,
stacked=True, color = colors, ec='black')
ax2.hist([tips['tip'],tips['tip']],bins = 10,orientation = 'horizontal',
stacked=True, color = colors, ec='black')
ax2.set_ylabel('')
graph_joint_histograms(tips)
plt.show()

Categories

Resources