如何修复在Streamlit应用的Matplotlib折线图中图例条目不匹配的问题?

huangapple go评论59阅读模式
英文:

How can I fix legend entries not matching with my matplotlib line chart on a streamlit app?

问题

以下是您提供的代码的翻译部分:

# Import libraries
import pandas as pd
import streamlit as st
import matplotlib.pyplot as plt

#----------------------- 应力 - 应变-----------------------
# 从源文件加载数据
df = pd.read_excel(
    io='MRE.xlsx',
    engine='openpyxl',
    sheet_name='Sheet1',
    skiprows=0,
    usecols='A:E',
    nrows=11168,
)

# 侧边栏 - 添加可用于筛选的内容
st.sidebar.header('输入应力和应变显示的筛选条件')

spec = st.sidebar.multiselect(
    '选择规格:',
    options=df['Spec'].unique(),
    default=df['Spec'].unique()
)

df_selection = df.query(
    'Spec == @spec'
)

# 绘制数据并添加图例、标题等...
fig = plt.figure()
ax = fig.add_subplot()
df_selection.groupby("Spec").plot(x="平均应变 (%)",
                                  y="平均应力 (MPa)",
                                  legend=False,
                                  ax=ax,
                                  linewidth=0.65,
                                  figsize=(10, 6))
plt.xlabel('应变 (%/100)')
plt.ylabel('应力 (MPa)')
plt.title('应力-应变图')
plt.grid(visible=True)

# 缩小当前轴底部的高度10%
# box = ax.get_position()
# ax.set_position([box.x0, box.y0 + box.height * 0.1,
#                   box.width, box.height * 0.9])

# 将图例放在当前轴下方
plt.legend(df_selection['Spec'].unique(), loc='upper center', bbox_to_anchor=(0.5, -0.15),
          ncol=5)
plt.show()
st.pyplot(fig)

请注意,上述翻译部分仅包括代码,不包括注释和图像的描述。如果您需要更多帮助或有其他问题,请随时提出。

英文:

I want to display a plot in a streamlit app. After selecting the spec in a sidebar widget, I display the selected graphs in a line chart. The problem I have is with the legend. When I select or unselect a spec, the graph is updated correctly but the legend is not.

So for example I have Specs 1 though 5 displayed correctly, but according to the legend Spec 1 is Spec 4, which is not true...

I tried filtering for different things and locating the legend entry at different locations, but that did nothing.
Below is my current code.

# Import libraries
import pandas as pd
import streamlit as st
import matplotlib.pyplot as plt

#----------------------- Stress - Strain-----------------------
# Load data from source file
df = pd.read_excel(
    io = 'MRE.xlsx',
    engine='openpyxl',
    sheet_name='Sheet1',
    skiprows=0,
    usecols='A:E',
    nrows=11168,
)

#SIDEBAR -> add things that can be filtered for
st.sidebar.header('Enter filter for Stress and Strain display')

spec = st.sidebar.multiselect(
    'Select spec:',
    options=df['Spec'].unique(),
    default=df['Spec'].unique()
)

df_selection = df.query(
    'Spec == @spec'
)

# Plot data and add legend, title, ...
fig = plt.figure()
ax = fig.add_subplot()
df_selection.groupby("Spec").plot(x="Average strain (%)",
                                  y="Average stress (MPa)",
                                  legend=False,
                                  ax=ax,
                                  linewidth = 0.65,
                                  figsize=(10,6))
plt.xlabel('Strain (%/100)')
plt.ylabel('Stress (MPa)')
plt.title('Stress-Strain diagram')
plt.grid(visible=True)

# Shrink current axis's height by 10% on the bottom
# box = ax.get_position()
# ax.set_position([box.x0, box.y0 + box.height * 0.1,
#                   box.width, box.height * 0.9])

# # Put a legend below current axis
plt.legend(df_selection['Spec'].unique(),loc='upper center', bbox_to_anchor=(0.5, -0.15),
          ncol=5)
plt.show()
st.pyplot(fig)

How the legend entry should look like vs. how it actually looks

如何修复在Streamlit应用的Matplotlib折线图中图例条目不匹配的问题?

Sorry, I don't know how to share the data for the df, so I'll share the github link.

答案1

得分: 0

I separated the data, so each spec has their own column. And then I used plt.plot on the new variables instead of the group_by. Seems to work for now.

t = pd.DataFrame();
u = pd.DataFrame();

    values = range(0,len(spec));

for i in values:
    t[i] = new_df_strain.iloc[:,i];
    u[i] = new_df_stress.iloc[:,i];

t2 = t.set_axis(axis = 1, labels = spec, inplace=False);
u2 = u set_axis(axis = 1, labels = spec, inplace=False);

# Plot data and add legend, title, ...

fig = plt.figure();
plt.rcParams['font.size'] = 35;
ax = fig.add_subplot();
plt.plot(t2,
     u2,
     linewidth = 1.5,);

plt.xlabel('Strain (%)');
plt.ylabel('Stress (MPa)');
英文:

Found a solution that seems to work, at least at the moment. I separated the data, so each spec has their own column. And then I used plt.plot on the new variables instead of the group_by. Seems to work for now.

t = pd.DataFrame();
u = pd.DataFrame();

    values = range(0,len(spec));

for i in values:
    t[i] = new_df_strain.iloc[:,i];
    u[i] = new_df_stress.iloc[:,i];

t2 = t.set_axis(axis = 1, labels = spec, inplace=False);
u2 = u.set_axis(axis = 1, labels = spec, inplace=False);

# Plot data and add legend, title, ...

fig = plt.figure();
plt.rcParams['font.size'] = 35;
ax = fig.add_subplot();
plt.plot(t2,
     u2,
     linewidth = 1.5,);

plt.xlabel('Strain (%)');
plt.ylabel('Stress (MPa)');

huangapple
  • 本文由 发表于 2023年5月26日 00:01:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76334259.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定