【问题标题】:Pyplot: Drawing figure in a custom scale (both x and y)Pyplot:以自定义比例绘制图形(x 和 y)
【发布时间】:2020-07-21 08:43:19
【问题描述】:

我一直在 Jupyter Notebook 中使用以下代码绘制数据框:为了与仅在纸上以 0.005mm=1cm 的比例提供的旧数据进行比较,我需要以相同的比例导出和打印图表:0.005图中的 mm(x 轴和 y 轴)在图中必须为 1cm。

有什么方法可以定义自定义比例吗?有关信息,x 范围和 y 范围不是固定的,它们会根据我加载到数据框中的数据而有所不同。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns            
import matplotlib.ticker as ticker


df = pd.DataFrame(np.array([[1.7, 0], [1.75, -0.012], [1.8, 0]]),
                   columns=['pos', 'val'])      
            
# Plot results
sns.set()
plt.figure(figsize=(20,30))

plt.plot(df['pos'], df['val'])

ax = plt.axes()
ax.set_aspect('equal')

plt.xlabel('Position [mm]')
plt.ylabel('Höhe [mm]')

ax.xaxis.set_major_locator(ticker.MultipleLocator(0.005))
ax.yaxis.set_major_locator(ticker.MultipleLocator(0.005))

plt.show()

【问题讨论】:

  • 我想,要对照一张旧纸质图表来检查你想打印你的情节,不是吗?在这种情况下,您必须①在绘图之前分析您的数据并确定图形的大小(以英寸为单位)以适应轴和②知道图形 dpi,您可以明确设置画布坐标(以像素为单位)和数据坐标之间的转换(请参阅 Matplotlib 文档中的转换教程)。如果你成功了,我建议你发布你的解决方案作为答案,因为这是一个有趣的问题,OTOH,如果你在 ping 我时遇到问题,我会尽力提供更多帮助......
  • @gboffi:我尝试按照您的建议解决问题。我定义了 x,y 限制并通过 (xmax-xmin)/0.005/2.54 计算了以英寸为单位的轴长度。我还阅读了转换教程,但我不明白如何将数据坐标转换为像素坐标可以帮助我解决问题。您能否更详细地说明您将如何处理它?
  • 我已经尝试过一段时间在matplotlib.transforms 模块中走自己的路,但它是镜子的迷宫……很抱歉,但暂时我会放弃。要回答您的问题,您需要一个真正的 Matplotlib 开发人员,所以我建议您尝试提高 an issue on Matplotlib's github
  • 我已经改变了重新转换的想法,并且我已经发布了我认为这是一个很好的、有效的答案。请您看一下并告诉我它是否在某些方面不令人满意?
  • 很好的解决方案。我不得不将 dpi=118 更改为 dpi=100,但现在比例完全符合我的要求。非常感谢!

标签: python matplotlib


【解决方案1】:

在一个 comment 我建议使用matplotlib.transforms——好吧,我错了 去就是无耻地窃取 Matplotlib 的Demo Fixed Size Axes...

(该图已由 StackOverflow 调整大小以适应帖子,但您 可以检查比例是否正确)

import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1 import Divider, Size
from mpl_toolkits.axes_grid1.mpl_axes import Axes

cm = lambda d: d/2.54

x, y = [1700.0, 1725.0, 1750.0], [0.0, -12.0, 0.0] # μm
dx, dy = 50.0, 12.0

# take margins into account
xmin, xmax = min(x)-dx*0.05, max(x)+dx*0.05
ymin, ymax = min(y)-dy*0.05, max(y)+dy*0.05
dx, dy = xmax-xmin, ymax-ymin

# 5 μm data == 1 cm plot
scale = 5/1
xlen, ylen = dx/scale, dy/scale

# Now we know the extents of our data and the axes dimension,
# so we can set the Figure dimensions, taking borders into account
left, right = 2, 1
bot, top = 1.5, 1.5
fig = plt.figure(
    figsize=(cm(left+xlen+right), cm(bot+ylen+top)),
    dpi=118)

# change bg color to show so that one can measure the figure
# and the axes when pasted into SO and do their math…
fig.set_facecolor('xkcd:grey teal')

##########  Below is stolen from Matplotlib Fixed Size Axes
########## (please don't ask me…)
# Origin and size of the x axis and y axis
h = [Size.Fixed(cm(left)), Size.Fixed(cm(xlen))]
v = [Size.Fixed(cm(bot)), Size.Fixed(cm(ylen))]
divider = Divider(fig, (0.0, 0.0, 1., 1.), h, v, aspect=False)
# NB: Axes is from mpl_toolkits.axes_grid1.mpl_axes
ax = Axes(fig, divider.get_position())
ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
fig.add_axes(ax)
#########  Above is stolen from Matplotlib Fixed Size Axes Demo 

plt.plot(x,y)
plt.grid()
ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax), yticks=range(-12,1,3),
       xlabel='X/μm', ylabel='Y/μm',
       title='X vs Y, 1 cm on plot equals 5 μm')
fig.suptitle('Figure dimensions: w = %.2f cm, h = %.2f cm.'%(
    left+xlen+right, bot+ylen+top))

fig.savefig('Figure_1.png',
            # https://stackoverflow.com/a/4805178/2749397, Joe Kington's
            facecolor=fig.get_facecolor(), edgecolor='none')

【讨论】:

    【解决方案2】:

    1 英寸 = 2.54 厘米,因此 254/0.005 = 50800 dpi

    plt.figure(figsize=(20,30), dpi=50800)
    

    【讨论】:

    • 尝试用 "plt.figure(figsize=(20,30), dpi=50800)" 替换 "plt.figure(figsize=(20,30))" 并得到 "ValueError: Image size 1016000x1524000 像素太大。每个方向必须小于 2^16。"
    • 我会重复自己的三个错误,但是您如何响应 dpi=5080 或 dpi=508,然后在打印时尝试将其放大 1000%?
    • 仍然会收到带有 5080 的 ValueError,但不会出现 508。
    • 我将以 DPI=508 进行打印,然后我将能够以我打印的放大副本作为回应。
    猜你喜欢
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多