英文:
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
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)');
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论