diff --git a/python-package/lightgbm/plotting.py b/python-package/lightgbm/plotting.py
index dd819aa5849..9cc7496cc17 100644
--- a/python-package/lightgbm/plotting.py
+++ b/python-package/lightgbm/plotting.py
@@ -13,11 +13,11 @@
def _check_not_tuple_of_2_elements(obj, obj_name='obj'):
"""Check object is not tuple or does not have 2 elements."""
if not isinstance(obj, tuple) or len(obj) != 2:
- raise TypeError('%s must be a tuple of 2 elements.' % obj_name)
+ raise TypeError(f"{obj_name} must be a tuple of 2 elements.")
def _float2str(value, precision=None):
- return ("{0:.{1}f}".format(value, precision)
+ return (f"{value:.{precision}f}"
if precision is not None and not isinstance(value, str)
else str(value))
@@ -207,7 +207,7 @@ def plot_split_value_histogram(booster, feature, bins=None, ax=None, width_coef=
hist, bins = booster.get_split_value_histogram(feature=feature, bins=bins, xgboost_style=False)
if np.count_nonzero(hist) == 0:
raise ValueError('Cannot plot split value histogram, '
- 'because feature {} was not used in splitting'.format(feature))
+ f'because feature {feature} was not used in splitting')
width = width_coef * (bins[1] - bins[0])
centred = (bins[:-1] + bins[1:]) / 2
@@ -393,21 +393,21 @@ def add(root, total_count, parent=None, decision=None):
operator = "="
else:
raise ValueError('Invalid decision type in tree model.')
- name = 'split{0}'.format(root['split_index'])
+ name = f"split{root['split_index']}"
if feature_names is not None:
- label = '{0} {1} '.format(feature_names[root['split_feature']], operator)
+ label = f"{feature_names[root['split_feature']]} {operator}"
else:
- label = 'feature {0} {1} '.format(root['split_feature'], operator)
- label += '{0}'.format(_float2str(root['threshold'], precision))
+ label = f"feature {root['split_feature']} {operator} "
+ label += f"{_float2str(root['threshold'], precision)}"
for info in ['split_gain', 'internal_value', 'internal_weight', "internal_count", "data_percentage"]:
if info in show_info:
output = info.split('_')[-1]
if info in {'split_gain', 'internal_value', 'internal_weight'}:
- label += '
{0} {1}'.format(_float2str(root[info], precision), output)
+ label += f"
{_float2str(root[info], precision)} {output}"
elif info == 'internal_count':
- label += '
{0}: {1}'.format(output, root[info])
+ label += f"
{output}: {root[info]}"
elif info == "data_percentage":
- label += '
{0}% of data'.format(_float2str(root['internal_count'] / total_count * 100, 2))
+ label += f"
{_float2str(root['internal_count'] / total_count * 100, 2)}% of data"
fillcolor = "white"
style = ""
@@ -417,21 +417,21 @@ def add(root, total_count, parent=None, decision=None):
if constraints[root['split_feature']] == -1:
fillcolor = "#ffdddd" # light red
style = "filled"
- label = "<" + label + ">"
+ label = f"<{label}>"
graph.node(name, label=label, shape="rectangle", style=style, fillcolor=fillcolor)
add(root['left_child'], total_count, name, l_dec)
add(root['right_child'], total_count, name, r_dec)
else: # leaf
- name = 'leaf{0}'.format(root['leaf_index'])
- label = 'leaf {0}: '.format(root['leaf_index'])
- label += '{0}'.format(_float2str(root['leaf_value'], precision))
+ name = f"leaf{root['leaf_index']}"
+ label = f"leaf {root['leaf_index']}: "
+ label += f"{_float2str(root['leaf_value'], precision)}"
if 'leaf_weight' in show_info:
- label += '
{0} weight'.format(_float2str(root['leaf_weight'], precision))
+ label += f"
{_float2str(root['leaf_weight'], precision)} weight"
if 'leaf_count' in show_info:
- label += '
count: {0}'.format(root['leaf_count'])
+ label += f"
count: {root['leaf_count']}"
if "data_percentage" in show_info:
- label += '
{0}% of data'.format(_float2str(root['leaf_count'] / total_count * 100, 2))
- label = "<" + label + ">"
+ label += f"
{_float2str(root['leaf_count'] / total_count * 100, 2)}% of data"
+ label = f"<{label}>"
graph.node(name, label=label)
if parent is not None:
graph.edge(parent, name, decision)