matplotlib 我怎样处理这个图形问题(不是圆线)?

tgabmvqs  于 2023-03-19  发布在  其他
关注(0)|答案(2)|浏览(194)

我想有一个好看的图表,使图上的线是圆的,但不幸的是,他们是加入“尖锐”。我的代码有什么问题。我错过了什么参数?

import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
import pandas as pd

def data_gr():
    fr = pd.read_csv('ramka_wynikowa.csv', sep=';')
    merged_df_database = fr

    # ustalenie kolorów linii
    line_colors = ['#8497B0', '#F6DD60', '#06A297']
    marker_colors = ['#5E7594', '#F2CD16', '#047068']

    # utworzenie wykresu słupkowego
    fig, ax = plt.subplots()
    ax.bar(merged_df_database.index, merged_df_database['quantity'], color='gray', alpha=0.6, edgecolor='none', width=0.8, label='quantity', capstyle='round')

    # dodanie danych do wykresu liniowego
    for i, col in enumerate(['value', 'value_up', 'rebate_value']):
        ax.plot(merged_df_database.index, merged_df_database[col], lw=4, solid_capstyle='round', color=line_colors[i], marker='o', markerfacecolor=marker_colors[i], markeredgecolor=marker_colors[i], linestyle='-', label=col)

    # dodanie legendy i tytułu
    ax.legend()
    ax.set_title('Wykres danych')

    # dodanie podpisów danych
    for x, y, q in zip(merged_df_database.index, merged_df_database['quantity'], merged_df_database['quantity']):
        ax.text(x, y, '{:.1f}'.format(q/1000), ha='center', va='bottom', fontsize=10)

    for col in ['value', 'value_up', 'rebate_value']:
        for x, y, v in zip(merged_df_database.index, merged_df_database[col], merged_df_database[col]):
            ax.text(x, y, '{:.1f}'.format(v/1000), ha='center', va='bottom')

    ax.set_yticks(ax.get_yticks())
    ax.set_yticklabels([f'{int(t / 1000)}' for t in ax.get_yticks()])
    plt.show()

输出:

以下是数据示例

invoice_num;salesman_id;market;quantity;value;customer;fv_date;surname;value_up;rebate_value;price_per_unit;;;
1001152;18;GE;7500.0;9005.12;BA125;12.01.2024;Odp;9725.529600000002;9005.12;1.2006826666666668;;;"7500.0;1.2"
1001154;12;GE;8200.0;9844.88;BA118;22.01.2024;Szy;10632.4704;9844.88;1.2005951219512194;;;"8200.0;1.2"
1001157;18;GE;6500.0;11712.42;AA088;25.01.2024;Odp;12649.413600000002;11712.42;1.8019107692307692;;;"6500.0;1.8"
1001159;18;GE;10300.0;19574.55;AC098;02.02.2024;Odp;21140.514;17617.095;1.9004417475728155;;;"10300.0;1.9"
1001161;18;GE;6900.0;11734.05;AD104;12.02.2024;Odp;12672.774;11734.05;1.700586956521739;;;"6900.0;1.7"
1001164;12;GE;12000.0;14410.85;BA138;15.02.2024;Szy;15563.718;12969.765000000001;1.2009041666666667;;;"12000.0;1.2"
1001166;12;GE;12300.0;25832.22;AF105;27.02.2024;Szy;27898.7976;23248.998000000003;2.100180487804878;;;"12300.0;2.1"
1001169;12;GE;10800.0;20526.42;AG222;03.03.2024;Szy;22168.5336;18473.778;1.9005944444444443;;;"10800.0;1.9"
1001171;18;GE;7500.0;13521.88;BA118;11.03.2024;Odpow;14603.6304;13521.88;1.8029173333333333;;;"7500.0;1.8"
1001174;18;GE;6900.0;11730.14;AH111;16.03.2024;Odpow;12668.5512;11730.14;1.7000202898550725;;;"6900.0;1.7"
ogsagwnx

ogsagwnx1#

Matplotlib的plot函数只是在点之间绘制直线(我认为您试图使用solid_capstyle='round'来“舍入”数据,但这实际上是errorbar图的一个参数,并设置了误差条的样式“caps”)。要获得“舍入”图,您需要执行一些平滑或插值,例如,使用scipy interpolate1d函数。例如:

from scipy.interpolate import interpolate1d
import numpy as np

...

for i, col in enumerate(['value', 'value_up', 'rebate_value']):
    # create intepolation function
    ifunc = interpolate1d(
        merged_df_database.index,
        merged_df_database[col],
        kind="cubic",
    )

    # get fine grid (say 500 points) of x-axis points at which to interpolate
    xgrid = np.linspace(
        merged_df_database.index[0],  # grid start value
        merged_df_database.index[-1],  # grid end value
        500,  # number of grid points
    )

    # plot (original) marker points (without lines inbetween)
    ax.plot(
        merged_df_database.index,
        merged_df_database[col],
        color=line_colors[i],
        marker='o',
        markerfacecolor=marker_colors[i],
        markeredgecolor=marker_colors[i],
        linestyle='none',
        label=col
    )
    

    # plot interpolated function
    ax.plot(
        xgrid,
        ifunc(xgrid),
        lw=4,
        color=line_colors[i],
        marker='o',
        markerfacecolor=marker_colors[i],
        markeredgecolor=marker_colors[i],
        linestyle='-',
    )

另请参见this question的答案。

njthzxwz

njthzxwz2#

修改后看起来有点奇怪。
enter image description here

merged_df_database = df_dict['merged_df_database']
    line_colors = ['#8497B0', '#F6DD60', '#06A297']
    marker_colors = ['#5E7594', '#F2CD16', '#047068']

    fig, ax = plt.subplots()
    ax.bar(merged_df_database.index, merged_df_database['quantity'], color='gray', alpha=0.6, edgecolor='none', width=0.8, label='quantity', capstyle='round')

    for i, col in enumerate(['value', 'value_up', 'rebate_value']):
        # create intepolation function
        ifunc = interp1d(
            merged_df_database.index,
            merged_df_database[col],
            kind="cubic",
        )

        # get fine grid (say 500 points) of x-axis points at which to interpolate
        xgrid = np.linspace(
            merged_df_database.index[0],  # grid start value
            merged_df_database.index[-1],  # grid end value
            500,  # number of grid points
        )

        # plot (original) marker points (without lines inbetween)
        ax.plot(
            merged_df_database.index,
            merged_df_database[col],
            color=line_colors[i],
            marker='o',
            markerfacecolor=marker_colors[i],
            markeredgecolor=marker_colors[i],
            linestyle='none',
            label=col
        )

        # plot interpolated function
        ax.plot(
            xgrid,
            ifunc(xgrid),
            lw=4,
            color=line_colors[i],
            marker='o',
            markerfacecolor=marker_colors[i],
            markeredgecolor=marker_colors[i],
            linestyle='-',
        )
    # dodanie legendy i tytułu
    ax.legend()
    ax.set_title('Wykres danych')

    # dodanie podpisów danych
    for x, y, q in zip(merged_df_database.index, merged_df_database['quantity'], merged_df_database['quantity']):
        ax.text(x, y, '{:.1f}'.format(q/1000), ha='center', va='bottom', fontsize=10)

    for col in ['value', 'value_up', 'rebate_value']:
        for x, y, v in zip(merged_df_database.index, merged_df_database[col], merged_df_database[col]):
            ax.text(x, y, '{:.1f}'.format(v/1000), ha='center', va='bottom')

    ax.set_yticks(ax.get_yticks())
    ax.set_yticklabels([f'{int(t / 1000)}' for t in ax.get_yticks()])
    plt.show()

相关问题