Setting row edge color of matplotlib table

2024/11/16 14:46:38

I've a pandas DataFrame plotted as a table using matplotlib (from this answer).

Now I want to set the bottom edge color of a given row and I've this code:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import sixdf = pd.DataFrame()
df['date'] = ['2016-04-01', '2016-04-02', '2016-04-03', '2016-04-04']
df['calories'] = [2200, 2100, 1500, 1800]
df['sleep hours'] = [2200, 2100, 1500, 1500]
df['gym'] = [True, False, False, True]def render_mpl_table(data, col_width=3.0, row_height=0.625, font_size=14,header_color='#40466e', row_colors=['#f1f1f2', 'w'], edge_color='w',bbox=[0, 0, 1, 1], header_columns=0,ax=None, **kwargs):if ax is None:size = (np.array(data.shape[::-1]) + np.array([0, 1])) * np.array([col_width, row_height])fig, ax = plt.subplots(figsize=size)ax.axis('off')mpl_table = ax.table(cellText=data.values, bbox=bbox, colLabels=data.columns, **kwargs)mpl_table.auto_set_font_size(False)mpl_table.set_fontsize(font_size)for k, cell in six.iteritems(mpl_table._cells):cell.set_edgecolor(edge_color)if k[0] == 0 or k[1] < header_columns:cell.set_text_props(weight='bold', color='w')cell.set_facecolor(header_color)else:cell.set_facecolor(row_colors[k[0]%len(row_colors) ])return axdef get_table(ax):table = Nonefor child in ax.get_children():if isinstance(child, matplotlib.table.Table):table = childreturn tablereturn tabledef set_row_edge_color(ax, row, color):table = get_table(ax)for k, cell in  six.iteritems(table._cells):if (k[0] == row):cell.set_edgecolor(color)ax = render_mpl_table(df, header_columns=0, col_width=2.0)
set_row_edge_color(ax, 2, 'k')
plt.show()

I'm unable to set only the color of row bottom and it gets set like this: enter image description here

Is there a way to set only the row bottom color like this?

enter image description here

Or is there a way to locate row in the figure/plot and draw a horizontal line?

Answer

There is no general way to make lines of different thickness or color on individual sides of cells (Rectangles) in matplotlib. In the case of the question, the solution is however quite easily obtained via ax.axhline() (as commented by @GAnderson) due to the table filling the entire bounding box of the axes.

You would first need to set the data range of the axes to range between -1 and the number of rows in the table. Then you can just plot an axhline at the position of choice.

There are only two line changed (which I marked with a comment) and it seems you can completely get rid of the get_table function.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import sixdf = pd.DataFrame()
df['date'] = ['2016-04-01', '2016-04-02', '2016-04-03', '2016-04-04']
df['calories'] = [2200, 2100, 1500, 1800]
df['sleep hours'] = [2200, 2100, 1500, 1500]
df['gym'] = [True, False, False, True]def render_mpl_table(data, col_width=3.0, row_height=0.625, font_size=14,header_color='#40466e', row_colors=['#f1f1f2', 'w'], edge_color='w',bbox=[0, 0, 1, 1], header_columns=0,ax=None, **kwargs):if ax is None:size = (np.array(data.shape[::-1]) + np.array([0, 1])) * np.array([col_width, row_height])fig, ax = plt.subplots(figsize=size)ax.axis('off')ax.axis([0,1,data.shape[0],-1])                ## <---------- Change herempl_table = ax.table(cellText=data.values, bbox=bbox, colLabels=data.columns, **kwargs)mpl_table.auto_set_font_size(False)mpl_table.set_fontsize(font_size)for k, cell in six.iteritems(mpl_table._cells):cell.set_edgecolor(edge_color)if k[0] == 0 or k[1] < header_columns:cell.set_text_props(weight='bold', color='w')cell.set_facecolor(header_color)else:cell.set_facecolor(row_colors[k[0]%len(row_colors) ])return axdef set_row_edge_color(ax, row, color):ax.axhline(y=row, color=color)                  ## <---------- Change hereax = render_mpl_table(df, header_columns=0, col_width=2.0)
set_row_edge_color(ax, 2, 'k')
plt.show()

enter image description here

https://en.xdnf.cn/q/71658.html

Related Q&A

TypeError: string indices must be integers (Python) [duplicate]

This question already has answers here:Why am I seeing "TypeError: string indices must be integers"?(10 answers)Closed 5 years ago.I am trying to retrieve the id value : ad284hdnn.I am getti…

how to split numpy array and perform certain actions on split arrays [Python]

Only part of this question has been asked before ([1][2]) , which explained how to split numpy arrays. I am quite new in Python. I have an array containing 262144 items and want to split it in small…

NLTK was unable to find the java file! for Stanford POS Tagger

I have been stuck trying to get the Stanford POS Tagger to work for a while. From an old SO post I found the following (slightly modified) code:stanford_dir = C:/Users/.../stanford-postagger-2017-06-09…

Append a list in Google Sheet from Python

I have a list in Python which I simply want to write (append) in the first column row-by-row in a Google Sheet. Im done with all the initial authentication part, and heres the code:credentials = Google…

Compute linear regression standardized coefficient (beta) with Python

I would like to compute the beta or standardized coefficient of a linear regression model using standard tools in Python (numpy, pandas, scipy.stats, etc.).A friend of mine told me that this is done in…

Individually labeled bars for bar graph in Plotly

I was trying to create annotations for grouped bar charts - where each bar has a specific data label that shows the value of that bar and is located above the centre of the bar.I tried a simple modific…

Is there a way to subclass a generator in Python 3?

Aside from the obvious, I thought Id try this, just in case:def somegen(input=None):...yield...gentype = type(somegen()) class subgen(gentype):def best_function_ever():...Alas, Pythons response was qui…

represent binary search trees in python

how do i represent binary search trees in python?

Python os.path.commonprefix - is there a path oriented function?

So I have this python code:print os.path.commonprefix([rC:\root\dir,rC:\root\dir1])Real ResultC:\root\dirDesired resultC:\rootQuestion 1Based on os.path.commonprefix documentation: Return the longest p…

Importing Stripe into Django - NameError

I cant seem to figure out how to import Stripe into my Django project. Im running Python 2.7.3 and I keep receiving NameError at /complete/ global name. stripe is not defined.Even when I just open up T…