Как изменить размер маркеров и ширину линий в боксплотах (pyplot) - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть следующий код, определяющий функцию:

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns;sns.set()
from Utils import cmp_iso_forest_od_params

## agg backend is used to create plot as a .png file
mpl.use('agg')

def print_boxplots(data: pd.DataFrame,
                   graph_filename: str,
                   col_examined: str,
                   col_related: str,
                   sort_func,
                   title: str,
                   x_title: str,
                   y_title: str,
                   min_val=None,
                   max_val=None
                   ):
    g = data.groupby([col_related])

    # graph parameters
    scale = 2
    show_fliers = True
    mean_color='b'
    mean_marker='o'


    labels = []
    data_to_plot_arr = []
    #switch = True


    for group, group_df in g:
        data_to_plot_arr.append(group_df[col_examined])
        labels.append(group)

    # dynamically set parameters of the graphs so that they are uniform across all graphs, but are minimalised
    figsize = ((len(g)) * scale, 25 * scale)  # originally (60, 30)
    if max_val is None:
        max_val = data[col_examined].max()
    if min_val is None:
        min_val = data[col_examined].min()
    tick = (max_val - min_val) / 40
    y_labels = np.concatenate([ np.arange(0, min_val-tick, -tick)[::-1], np.arange(0, max_val+6*tick, tick)])

    # Create a figure instance
    _fig = plt.figure( figsize=figsize)

    # Create an axes instance
    _ax = _fig.add_subplot(111)
    _ax.set_xlabel(col_related, fontsize=20*scale)
    # this sorts times and labels for display in the boxplot by the parameters of the boxplots
    data_to_plot_arr, labels = zip(*sorted(zip(data_to_plot_arr,labels), key=sort_func ))

    # Create the boxplot

    bp = _ax.boxplot(data_to_plot_arr, positions=[x for x in range(len(labels))], showfliers=show_fliers)
    # following function is described here: https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot
    _ax.plot([x for x in range(len(labels))], list(map(lambda x: x.mean(), list(data_to_plot_arr))), marker=mean_marker, color=mean_color)
    _ax.set_title(title,
                  fontsize=25 * scale)
    _ax.set_xlabel(x_title, fontsize=25 * scale)
    _ax.set_ylabel(y_title, rotation=90, fontsize=25 * scale)
    _ax.set_xticklabels(labels, rotation=90)
    _ax.set_yticks(y_labels)
    _ax.tick_params(axis='x', labelsize=22*scale)
    _ax.tick_params(axis='y', labelsize=22*scale)

    # custom legend elements gymnastics (it is really awful, but I coudl not find better solution)
    colors = [mean_color]
    sizes = [6*scale]
    texts = ["Mean"]
    patches = [plt.plot([], [], marker=mean_marker, ms=sizes[i], ls="", mec=None, color=colors[i],
                        label="{:s}".format(texts[i]))[0] for i in range(len(texts))]

    legend = plt.legend(handles=patches,
                        bbox_to_anchor=[0.5, -0.08],
                        loc='center',
                        title="Boxplots show first and third quartile,\n with variability represented with whiskers",
                        ncol=2,
                        prop={'size': 16 * scale})
    legend.get_title().set_fontsize(16 * scale)
    _ax.grid(True)



    # Save the figure
    _fig.savefig(graph_filename+'.png', bbox_inches='tight')

Что он делает, это сохраняет серию коробочных графиков с нанесенными на график средствами в файл.

Мне нужно настроить толщина линий и размер всех маркеров на графике по отношению к параметру scale, поэтому я могу контролировать определение конечного изображения. Мне не удалось найти какие-либо полезные параметры в документации, поэтому я оказался здесь.

Текущий пример изображения выглядит так: the lines are too thin and markers too small

...