Streamlit中Matplotlib非标准格式绘图分辨率低问题排查与解决
Streamlit中Pandas绘图分辨率极低的问题解析与解决
问题重现
你遇到的情况很典型:同样的figsize设置,在Jupyter Notebook里绘图清晰,但放到Streamlit中就变得模糊。你的示例代码如下:
import pandas as pd import numpy as np import streamlit as st index = pd.date_range(start='2019-01-01', periods=31) data = np.random.randint(0,100,size=(len(index))) df = pd.DataFrame(index=index, data=data) df.plot(figsize=(25, 5), antialiased=True) st.pyplot(dpi=100)
问题成因
这背后主要是Streamlit对Matplotlib图表的渲染逻辑和Jupyter不同:
- 当你用
df.plot()时,Pandas会自动创建一个Matplotlib的Figure对象,这个对象默认使用Matplotlib的全局dpi设置(通常是100)。你设置的figsize=(25,5)是基于这个默认dpi的画布尺寸。 - 在Jupyter中,图表是直接渲染Matplotlib的原生Figure,Jupyter会根据显示环境自动适配,所以看起来清晰。
- 但在Streamlit中,
st.pyplot()会把Matplotlib的Figure导出为图片,再渲染到页面上。如果Figure本身的dpi不够,即使你在st.pyplot()里指定dpi=100,也只是基于低分辨率的Figure导出,后续Streamlit页面缩放时就会显得模糊。
解决方法
这里有几种可靠的修复方式,按推荐度排序:
1. 手动创建高dpi的Figure对象
最稳妥的方式是自己创建Matplotlib的Figure和Axes,明确指定高dpi,再让Pandas绘图到这个Axes上:
import pandas as pd import numpy as np import streamlit as st import matplotlib.pyplot as plt index = pd.date_range(start='2019-01-01', periods=31) data = np.random.randint(0,100,size=(len(index))) df = pd.DataFrame(index=index, data=data) # 创建指定dpi的画布,这里设为150(可根据需求调整) fig, ax = plt.subplots(figsize=(25, 5), dpi=150) # 让Pandas在指定的Axes上绘图 df.plot(ax=ax, antialiased=True) # 传入创建好的fig给st.pyplot st.pyplot(fig)
这种方式从根源上提升了画布的分辨率,导出的图片自然清晰。
2. 提高st.pyplot的dpi参数
如果你不想手动创建Figure,可以直接在st.pyplot()中设置更高的dpi值(比如150或200),强制Matplotlib导出更高分辨率的图片:
df.plot(figsize=(25, 5), antialiased=True) st.pyplot(dpi=150)
不过这种方式依赖Matplotlib对低分辨率Figure的放大,效果可能不如第一种稳定。
3. 使用Streamlit原生图表组件
如果你的图表不需要复杂的Matplotlib自定义,推荐直接用Streamlit的原生st.line_chart(),它会自适应页面尺寸,渲染效果更清晰:
st.line_chart(df)
原生组件不仅分辨率更好,加载速度也更快,还支持交互(比如缩放、hover显示数据)。
内容的提问来源于stack exchange,提问作者mjspier
相关产品推荐
相关产品推荐

