标签归档:matplotlib

从Matplotlib的颜色图中获取单个颜色

问题:从Matplotlib的颜色图中获取单个颜色

cmap例如,如果您有一个Colormap :

cmap = matplotlib.cm.get_cmap('Spectral')

如何从0到1之间获得特定的颜色,其中0是地图中的第一种颜色,而1是地图中的最后一种颜色?

理想情况下,我可以通过执行以下操作来获得地图中的中间颜色:

>>> do_some_magic(cmap, 0.5) # Return an RGBA tuple
(0.1, 0.2, 0.3, 1.0)

If you have a Colormap cmap, for example:

cmap = matplotlib.cm.get_cmap('Spectral')

How can you get a particular colour out of it between 0 and 1, where 0 is the first colour in the map and 1 is the last colour in the map?

Ideally, I would be able to get the middle colour in the map by doing:

>>> do_some_magic(cmap, 0.5) # Return an RGBA tuple
(0.1, 0.2, 0.3, 1.0)

回答 0

您可以使用下面的代码来执行此操作,而问题中的代码实际上与所需的代码非常接近,您所要做的就是调用cmap您拥有的对象。

import matplotlib

cmap = matplotlib.cm.get_cmap('Spectral')

rgba = cmap(0.5)
print(rgba) # (0.99807766255210428, 0.99923106502084169, 0.74602077638401709, 1.0)

对于[0.0,1.0]范围之外的值,它将分别返回底色和底色。默认情况下,这是该范围内的最小和最大颜色(即0.0和1.0)。可以使用cmap.set_under()和更改默认设置cmap.set_over()

对于“特殊”数字(例如)np.nannp.inf默认值是使用0.0值,可以使用cmap.set_bad()类似于“低于”和“高于”的方式更改此值。

最后,您可能需要对数据进行规范化以使其符合范围[0.0, 1.0]matplotlib.colors.Normalize只需使用下面的小示例所示,即可完成此操作,在该示例中,参数vminvmax描述应分别映射到0.0和1.0的数字。

import matplotlib

norm = matplotlib.colors.Normalize(vmin=10.0, vmax=20.0)

print(norm(15.0)) # 0.5

对数归一化器(matplotlib.colors.LogNorm)也可用于值范围较大的数据范围。

(感谢Joe Kingtontcaswell提出了有关如何改善答案的建议。)

You can do this with the code below, and the code in your question was actually very close to what you needed, all you have to do is call the cmap object you have.

import matplotlib

cmap = matplotlib.cm.get_cmap('Spectral')

rgba = cmap(0.5)
print(rgba) # (0.99807766255210428, 0.99923106502084169, 0.74602077638401709, 1.0)

For values outside of the range [0.0, 1.0] it will return the under and over colour (respectively). This, by default, is the minimum and maximum colour within the range (so 0.0 and 1.0). This default can be changed with cmap.set_under() and cmap.set_over().

For “special” numbers such as np.nan and np.inf the default is to use the 0.0 value, this can be changed using cmap.set_bad() similarly to under and over as above.

Finally it may be necessary for you to normalize your data such that it conforms to the range [0.0, 1.0]. This can be done using matplotlib.colors.Normalize simply as shown in the small example below where the arguments vmin and vmax describe what numbers should be mapped to 0.0 and 1.0 respectively.

import matplotlib

norm = matplotlib.colors.Normalize(vmin=10.0, vmax=20.0)

print(norm(15.0)) # 0.5

A logarithmic normaliser (matplotlib.colors.LogNorm) is also available for data ranges with a large range of values.

(Thanks to both Joe Kington and tcaswell for suggestions on how to improve the answer.)


回答 1

为了获得rgba整数值而不是float值,我们可以

rgba = cmap(0.5,bytes=True)

因此,为了简化基于Ffisegydd的答案的代码,代码将如下所示:

#import colormap
from matplotlib import cm

#normalize item number values to colormap
norm = matplotlib.colors.Normalize(vmin=0, vmax=1000)

#colormap possible values = viridis, jet, spectral
rgba_color = cm.jet(norm(400),bytes=True) 

#400 is one of value between 0 and 1000

In order to get rgba integer value instead of float value, we can do

rgba = cmap(0.5,bytes=True)

So to simplify the code based on answer from Ffisegydd, the code would be like this:

#import colormap
from matplotlib import cm

#normalize item number values to colormap
norm = matplotlib.colors.Normalize(vmin=0, vmax=1000)

#colormap possible values = viridis, jet, spectral
rgba_color = cm.jet(norm(400),bytes=True) 

#400 is one of value between 0 and 1000

回答 2

为了建立在Ffisegyddamaliammr的解决方案的基础上,这是一个示例,其中我们为自定义颜色图制作CSV表示形式:

#! /usr/bin/env python3
import matplotlib
import numpy as np 

vmin = 0.1
vmax = 1000

norm = matplotlib.colors.Normalize(np.log10(vmin), np.log10(vmax))
lognum = norm(np.log10([.5, 2., 10, 40, 150,1000]))

cdict = {
    'red':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 1, 1),
        (lognum[3], 0.8, 0.8),
        (lognum[4], .7, .7),
    (lognum[5], .7, .7)
    ),
    'green':
    (
        (0., .6, .6),
        (lognum[0], 0.8, 0.8),
        (lognum[1], 1, 1),
        (lognum[2], 1, 1),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 0, 0)
    ),
    'blue':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 0, 0),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 1, 1)
    )
}


mycmap = matplotlib.colors.LinearSegmentedColormap('my_colormap', cdict, 256)   
norm = matplotlib.colors.LogNorm(vmin, vmax)
colors = {}
count = 0
step_size = 0.001
for value in np.arange(vmin, vmax+step_size, step_size):
    count += 1
    print("%d/%d %f%%" % (count, vmax*(1./step_size), 100.*count/(vmax*(1./step_size))))
    rgba = mycmap(norm(value), bytes=True)
    color = (rgba[0], rgba[1], rgba[2])
    if color not in colors.values():
        colors[value] = color

print ("value, red, green, blue")
for value in sorted(colors.keys()):
    rgb = colors[value]
    print("%s, %s, %s, %s" % (value, rgb[0], rgb[1], rgb[2]))

To build on the solutions from Ffisegydd and amaliammr, here’s an example where we make CSV representation for a custom colormap:

#! /usr/bin/env python3
import matplotlib
import numpy as np 

vmin = 0.1
vmax = 1000

norm = matplotlib.colors.Normalize(np.log10(vmin), np.log10(vmax))
lognum = norm(np.log10([.5, 2., 10, 40, 150,1000]))

cdict = {
    'red':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 1, 1),
        (lognum[3], 0.8, 0.8),
        (lognum[4], .7, .7),
    (lognum[5], .7, .7)
    ),
    'green':
    (
        (0., .6, .6),
        (lognum[0], 0.8, 0.8),
        (lognum[1], 1, 1),
        (lognum[2], 1, 1),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 0, 0)
    ),
    'blue':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 0, 0),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 1, 1)
    )
}


mycmap = matplotlib.colors.LinearSegmentedColormap('my_colormap', cdict, 256)   
norm = matplotlib.colors.LogNorm(vmin, vmax)
colors = {}
count = 0
step_size = 0.001
for value in np.arange(vmin, vmax+step_size, step_size):
    count += 1
    print("%d/%d %f%%" % (count, vmax*(1./step_size), 100.*count/(vmax*(1./step_size))))
    rgba = mycmap(norm(value), bytes=True)
    color = (rgba[0], rgba[1], rgba[2])
    if color not in colors.values():
        colors[value] = color

print ("value, red, green, blue")
for value in sorted(colors.keys()):
    rgb = colors[value]
    print("%s, %s, %s, %s" % (value, rgb[0], rgb[1], rgb[2]))

回答 3

为了完整起见,这些是我到目前为止遇到的cmap选择:

重音,重音,蓝调,蓝调,BrBG,BrBG_r,BuGn,BuGn_r,BuPu,BuPu_r,CMRmap,CMRmap_r,Dark2,Dark2_r,GnBu,GnBu_r,Greens,Greens_r,Greys,Greys_r,Orange,Rr,OrRd,OrRd PRGn_r,成对,成对_r,Pastel1,Pastel1_r,Pastel2,Pastel2_r,PiYG,PiYG_r,PuBu,PuBuGn,PuBuGn_r,PuBu_r,PuOr,PuOr_r,PuRd,PuRd_r,Puror,PurOr_r,RdBu,RdBu,RdBu,RdBu,RdBu,RdBu,RdBu,RdBu,RdBu,RdBu,RdBu,RdBu RdYlBu,RdYlBu_r,RdYlGn,RdYlGn_r,Reds,Reds_r,Set1,Set1_r,Set2,Set2_r,Set3,Set3_r,Spectral,Spectral_r,Wistia,Wistia_r,YlGn,YlGnBu,YlGnBr_r,YlGnBr_r,YlGnBr_r,YlGnBr_r,YlGnBr_r,YlGnBr afmhot_r,秋季,autumn_r,二进制,binary_r,骨骼,bone_r,brg,brg_r,bwr,bwr_r,cividis,cividis_r,cool,cool_r,coolwarm,coolwarm_r,铜,copper_r,cubehelix,cubehelix_r,标志,flag_r,gist_eargist_gray,gist_gray_r,gist_heat,gist_heat_r,gist_ncar,gist_ncar_r,gist_rainbow,gist_rainbow_r,gist_stern,gist_stern_r,gist_yarg,gist_yarg_r,gnuplots,gn_lotv,gnuplot,gnuplot2,gnuplot2,gnuplot2,gnuplot2, jet_r,岩浆,岩浆_r,nipy_spectral,nipy_spectral_r,海洋,ocean_r,粉红色,pink_r,等离子,plasma_r,棱镜,prism_r,彩虹,rainbow_r,地震,地震_r,弹​​簧,spring_r,夏季,summer_r,tab10,tab10_r,tab20,tab20_r, tab20b,tab20b_r,tab20c,tab20c_r,terrain,terrain_r,twilight,twilight_r,twilight_shifted,twilight_shifted_r,viridis,viridis_r,冬天,winter_rgray_r,hot,hot_r,hsv,hsv_r,地狱,inferno_r,喷射,jet_r,岩浆,岩浆_r,nipy_spectral,nipy_spectral_r,海洋,ocean_r,粉红色,pink_r,等离子,plasma_r,棱镜,prism_r,彩虹,rainbow_r,地震,地震_r,春天,spring_r,夏天,summer_r,tab10,tab10_r,tab20,tab20_r,tab20b,tab20b_r,tab20c,tab20c_r,terrain,terrain_r,twilight,twilight_r,twilight_shifted,twilight_shifted_r,viridis,viridis_r,冬天,winter_rgray_r,hot,hot_r,hsv,hsv_r,地狱,inferno_r,喷射,jet_r,岩浆,岩浆_r,nipy_spectral,nipy_spectral_r,海洋,ocean_r,粉红色,pink_r,等离子,plasma_r,棱镜,prism_r,彩虹,rainbow_r,地震,地震_r,春天,spring_r,夏天,summer_r,tab10,tab10_r,tab20,tab20_r,tab20b,tab20b_r,tab20c,tab20c_r,terrain,terrain_r,twilight,twilight_r,twilight_shifted,twilight_shifted_r,viridis,viridis_r,冬天,winter_rviridis,viridis_r,冬天,winter_rviridis,viridis_r,冬天,winter_r

For completeness these are the cmap choices I encountered so far:

Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens, Greens_r, Greys, Greys_r, OrRd, OrRd_r, Oranges, Oranges_r, PRGn, PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Purples, Purples_r, RdBu, RdBu_r, RdGy, RdGy_r, RdPu, RdPu_r, RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spectral, Spectral_r, Wistia, Wistia_r, YlGn, YlGnBu, YlGnBu_r, YlGn_r, YlOrBr, YlOrBr_r, YlOrRd, YlOrRd_r, afmhot, afmhot_r, autumn, autumn_r, binary, binary_r, bone, bone_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, cool, cool_r, coolwarm, coolwarm_r, copper, copper_r, cubehelix, cubehelix_r, flag, flag_r, gist_earth, gist_earth_r, gist_gray, gist_gray_r, gist_heat, gist_heat_r, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gnuplot, gnuplot2, gnuplot2_r, gnuplot_r, gray, gray_r, hot, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, seismic, seismic_r, spring, spring_r, summer, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terrain, terrain_r, twilight, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, winter, winter_r


如何使用python / matplotlib为3D图设置“相机位置”?

问题:如何使用python / matplotlib为3D图设置“相机位置”?

我正在学习如何使用mplot3d生成漂亮的3d数据图,到目前为止我还很高兴。我现在想做的是旋转表面的动画效果。为此,我需要为3D投影设置相机位置。我猜这一定是可能的,因为在交互使用matplotlib时,可以使用鼠标旋转表面。但是如何从脚本执行此操作?我在mpl_toolkits.mplot3d.proj3d中发现了很多转换,但是我找不到如何使用这些转换的目的,也没有找到任何尝试的示例。

I’m learning how to use mplot3d to produce nice plots of 3d data and I’m pretty happy so far. What I am trying to do at the moment is a little animation of a rotating surface. For that purpose, I need to set a camera position for the 3D projection. I guess this must be possible since a surface can be rotated using the mouse when using matplotlib interactively. But how can I do this from a script? I found a lot of transforms in mpl_toolkits.mplot3d.proj3d but I could not find out how to use these for my purpose and I didn’t find any example for what I’m trying to do.


回答 0

通过“摄像机位置”,听起来好像您想调整用于查看3D图的仰角和方位角。您可以使用设置ax.view_init。我使用以下脚本首先创建了绘图,然后确定了一个合适的高程(或)elev,从中可以查看我的绘图。然后,我调整了方位角或azim,以改变绘图周围的整个360度,并保存了每个实例的图形(并在保存绘图时记下了哪个方位角)。对于更复杂的相机镜头,您可以同时调整仰角和角度以达到所需的效果。

    from mpl_toolkits.mplot3d import Axes3D
    ax = Axes3D(fig)
    ax.scatter(xx,yy,zz, marker='o', s=20, c="goldenrod", alpha=0.6)
    for ii in xrange(0,360,1):
        ax.view_init(elev=10., azim=ii)
        savefig("movie%d.png" % ii)

By “camera position,” it sounds like you want to adjust the elevation and the azimuth angle that you use to view the 3D plot. You can set this with ax.view_init. I’ve used the below script to first create the plot, then I determined a good elevation, or elev, from which to view my plot. I then adjusted the azimuth angle, or azim, to vary the full 360deg around my plot, saving the figure at each instance (and noting which azimuth angle as I saved the plot). For a more complicated camera pan, you can adjust both the elevation and angle to achieve the desired effect.

    from mpl_toolkits.mplot3d import Axes3D
    ax = Axes3D(fig)
    ax.scatter(xx,yy,zz, marker='o', s=20, c="goldenrod", alpha=0.6)
    for ii in xrange(0,360,1):
        ax.view_init(elev=10., azim=ii)
        savefig("movie%d.png" % ii)

回答 1

方便的是将“摄影机”位置应用于新图。因此,我进行绘图,然后使用鼠标更改距离来移动绘图。然后尝试复制包含另一图上距离的视图。我发现axx.ax.get_axes()为我提供了一个带有旧.azim和.elev的对象。

在PYTHON中…

axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev
dst=axx.dist       # ALWAYS GIVES 10
#dst=ax1.axes.dist # ALWAYS GIVES 10
#dst=ax1.dist      # ALWAYS GIVES 10

以后的3D图形…

ax2.view_init(elev=ele, azim=azm) #Works!
ax2.dist=dst                       # works but always 10 from axx

编辑1 …好,关于.dist值,相机位置是错误的思维方式。它作为整个图形的一种hackey标量乘法器而位于一切之上。

这适用于视图的放大/缩放:

xlm=ax1.get_xlim3d() #These are two tupples
ylm=ax1.get_ylim3d() #we use them in the next
zlm=ax1.get_zlim3d() #graph to reproduce the magnification from mousing
axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev

以后的图…

ax2.view_init(elev=ele, azim=azm) #Reproduce view
ax2.set_xlim3d(xlm[0],xlm[1])     #Reproduce magnification
ax2.set_ylim3d(ylm[0],ylm[1])     #...
ax2.set_zlim3d(zlm[0],zlm[1])     #...

What would be handy would be to apply the Camera position to a new plot. So I plot, then move the plot around with the mouse changing the distance. Then try to replicate the view including the distance on another plot. I find that axx.ax.get_axes() gets me an object with the old .azim and .elev.

IN PYTHON…

axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev
dst=axx.dist       # ALWAYS GIVES 10
#dst=ax1.axes.dist # ALWAYS GIVES 10
#dst=ax1.dist      # ALWAYS GIVES 10

Later 3d graph…

ax2.view_init(elev=ele, azim=azm) #Works!
ax2.dist=dst                       # works but always 10 from axx

EDIT 1… OK, Camera position is the wrong way of thinking concerning the .dist value. It rides on top of everything as a kind of hackey scalar multiplier for the whole graph.

This works for the magnification/zoom of the view:

xlm=ax1.get_xlim3d() #These are two tupples
ylm=ax1.get_ylim3d() #we use them in the next
zlm=ax1.get_zlim3d() #graph to reproduce the magnification from mousing
axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev

Later Graph…

ax2.view_init(elev=ele, azim=azm) #Reproduce view
ax2.set_xlim3d(xlm[0],xlm[1])     #Reproduce magnification
ax2.set_ylim3d(ylm[0],ylm[1])     #...
ax2.set_zlim3d(zlm[0],zlm[1])     #...

如何在matplotlib中删除上轴和右轴?

问题:如何在matplotlib中删除上轴和右轴?

而不是默认的“装箱”轴样式,我只希望有左轴和底轴,即:

+------+         |
|      |         |
|      |   --->  |
|      |         |
+------+         +-------

这应该很容易,但是我在文档中找不到必要的选项。

Instead of the default “boxed” axis style I want to have only the left and bottom axis, i.e.:

+------+         |
|      |         |
|      |   --->  |
|      |         |
+------+         +-------

This should be easy, but I can’t find the necessary options in the docs.


回答 0

这是官方网站HERE推荐的Matplotlib 3解决方案:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

ax = plt.subplot(111)
ax.plot(x, y)

# Hide the right and top spines
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

# Only show ticks on the left and bottom spines
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')

plt.show()

This is the suggested Matplotlib 3 solution from the official website HERE:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

ax = plt.subplot(111)
ax.plot(x, y)

# Hide the right and top spines
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

# Only show ticks on the left and bottom spines
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')

plt.show()


回答 1

或者,这

def simpleaxis(ax):
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()

似乎在轴上实现了相同的效果,而不会丢失旋转的标签支撑。

(Matplotlib 1.0.1;溶液的启发)。

Alternatively, this

def simpleaxis(ax):
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()

seems to achieve the same effect on an axis without losing rotated label support.

(Matplotlib 1.0.1; solution inspired by this).


回答 2

[edit] matplotlib现已发布(2013-10),版本为1.3.0,其中包括

该功能实际上只是添加的,您需要使用Subversion版本。您可以在此处查看示例代码。

我只是想说现在在线上有一个更好的例子。尽管仍然需要Subversion版本,但尚未发布。

[编辑] Matplotlib 0.99.0 RC1刚刚发布,并包含此功能。

[edit] matplotlib in now (2013-10) on version 1.3.0 which includes this

That ability was actually just added, and you need the Subversion version for it. You can see the example code here.

I am just updating to say that there’s a better example online now. Still need the Subversion version though, there hasn’t been a release with this yet.

[edit] Matplotlib 0.99.0 RC1 was just released, and includes this capability.


回答 3

(除了此处的全面答案之外,这更多是扩展注释。)


请注意,我们可以彼此独立地隐藏这三个元素中的每个元素:

  • 隐藏边框(又称“脊椎”):ax.set_frame_on(False)ax.spines['top'].set_visible(False)

  • 隐藏刻度线: ax.tick_params(top=False)

  • 隐藏标签: ax.tick_params(labeltop=False)

(This is more of an extension comment, in addition to the comprehensive answers here.)


Note that we can hide each of these three elements independently of each other:

  • To hide the border (aka “spine”): ax.set_frame_on(False) or ax.spines['top'].set_visible(False)

  • To hide the ticks: ax.tick_params(top=False)

  • To hide the labels: ax.tick_params(labeltop=False)


回答 4

如果不需要刻度线(例如用于绘制定性插图),则也可以使用以下快速解决方法:

使轴不可见(例如使用plt.gca().axison = False),然后使用手动绘制它们plt.arrow

If you don’t need ticks and such (e.g. for plotting qualitative illustrations) you could also use this quick workaround:

Make the axis invisible (e.g. with plt.gca().axison = False) and then draw them manually with plt.arrow.


回答 5

图书馆Seaborn具有内置的函数despine()。

只需添加:

import seaborn as sns

现在创建图形。并在末尾添加:

sns.despine()

如果查看该函数的某些默认参数值,它将删除顶部和右侧的书脊,并保留底部和左侧的书脊:

sns.despine(top=True, right=True, left=False, bottom=False)

在此处查看更多文档:https : //seaborn.pydata.org/generation/seaborn.despine.html

Library Seaborn has this built in with function despine().

Just add:

import seaborn as sns

Now create your graph. And add at the end:

sns.despine()

If you look at some of the default parameter values of the function it removes the top and right spine and keeps the bottom and left spine:

sns.despine(top=True, right=True, left=False, bottom=False)

Check out further documentation here: https://seaborn.pydata.org/generated/seaborn.despine.html


回答 6

如果需要从所有绘图中删除它,则可以在样式设置(样式表或rcParams)中删除刺。例如:

import matplotlib as mpl

mpl.rcParams['axes.spines.right'] = False
mpl.rcParams['axes.spines.top'] = False

如果要删除所有刺:

mpl.rcParams['axes.spines.left'] = False
mpl.rcParams['axes.spines.right'] = False
mpl.rcParams['axes.spines.top'] = False
mpl.rcParams['axes.spines.bottom'] = False

If you need to remove it from all your plots, you can remove spines in style settings (style sheet or rcParams). E.g:

import matplotlib as mpl

mpl.rcParams['axes.spines.right'] = False
mpl.rcParams['axes.spines.top'] = False

If you want to remove all spines:

mpl.rcParams['axes.spines.left'] = False
mpl.rcParams['axes.spines.right'] = False
mpl.rcParams['axes.spines.top'] = False
mpl.rcParams['axes.spines.bottom'] = False

numpy,scipy,matplotlib和pylab之间的混淆

问题:numpy,scipy,matplotlib和pylab之间的混淆

Numpy,scipy,matplotlib和pylab是使用python进行科学计算的常用术语。

我只是学习了一些有关pylab的知识,而感到困惑。每当我要导入numpy时,我都可以执行以下操作:

import numpy as np

我只是认为,一旦我这样做

from pylab import *

numpy也将被导入(使用np别名)。所以基本上,第二个相比第一个做更多的事情。

我想问的几件事:

  1. pylab仅仅是numpy,scipy和matplotlib的包装吗?
  2. 由于NP是pylab中的numpy别名,因此pylab中的scipy和matplotlib别名是什么?(据我所知,plt是matplotlib.pyplot的别名,但我不知道matplotlib本身的别名)

Numpy, scipy, matplotlib, and pylab are common terms among they who use python for scientific computation.

I just learn a bit about pylab, and I got confused. Whenever I want to import numpy, I can always do:

import numpy as np

I just consider, that once I do

from pylab import *

the numpy will be imported as well (with np alias). So basically the second one does more things compared to the first one.

There are few things I want to ask:

  1. Is it right that pylab is just a wrapper for numpy, scipy and matplotlib?
  2. As np is the numpy alias in pylab, what is the scipy and matplotlib alias in pylab? (as far as I know, plt is alias of matplotlib.pyplot, but I don’t know the alias for the matplotlib itself)

回答 0

  1. 没有,pylab是的一部分matplotlib(在matplotlib.pylab),并试图给你喜欢的环境Matlab的。matplotlib有许多依赖项,其中有一些依赖项numpy以通用别名导入npscipy不是的依赖项matplotlib

  2. 如果运行ipython --pylab自动导入,则会将所有符号从中matplotlib.pylab放入全局范围。就像您写的一样numpy,在np别名下导入。别名matplotlib下的符号来自mpl

  1. No, pylab is part of matplotlib (in matplotlib.pylab) and tries to give you a MatLab like environment. matplotlib has a number of dependencies, among them numpy which it imports under the common alias np. scipy is not a dependency of matplotlib.

  2. If you run ipython --pylab an automatic import will put all symbols from matplotlib.pylab into global scope. Like you wrote numpy gets imported under the np alias. Symbols from matplotlib are available under the mpl alias.


回答 1

Scipy和numpy是科学项目,旨在为python带来高效,快速的数值计算。

Matplotlib是python绘图库的名称。

Pyplot是matplotlib的交互式api,主要用于jupyter之类的笔记本中。您通常会这样使用它:import matplotlib.pyplot as plt

Pylab与pyplot相同,但是具有额外的功能(目前不鼓励使用)。

  • pylab = pyplot + numpy的

在此处查看更多信息:Matplotlib,Pylab,Pyplot等:这些和何时使用它们有什么区别?

Scipy and numpy are scientific projects whose aim is to bring efficient and fast numeric computing to python.

Matplotlib is the name of the python plotting library.

Pyplot is an interactive api for matplotlib, mostly for use in notebooks like jupyter. You generally use it like this: import matplotlib.pyplot as plt.

Pylab is the same thing as pyplot, but with extra features (its use is currently discouraged).

  • pylab = pyplot + numpy

See more information here: Matplotlib, Pylab, Pyplot, etc: What’s the difference between these and when to use each?


回答 2

由于某些示例(例如我)可能仍然对pylab的使用感到困惑,因为pylab互联网上存在使用示例的示例,因此这里引用了官方matplotlib常见问题解答:

pylab是一个便捷模块,可在单个命名空间中批量导入matplotlib.pyplot(用于绘图)和numpy(用于数学以及使用数组)。尽管许多示例都使用pylab,但不再建议使用。

因此,TL; DR; 是不使用pylab,句点。根据需要分别使用pyplot和导入numpy

这是进一步阅读和其他有用示例的链接

Since some people (like me) may still be confused about usage of pylab since examples using pylab are out there on the internet, here is a quote from the official matplotlib FAQ:

pylab is a convenience module that bulk imports matplotlib.pyplot (for plotting) and numpy (for mathematics and working with arrays) in a single name space. Although many examples use pylab, it is no longer recommended.

So, TL;DR; is do not use pylab, period. Use pyplot and import numpy separately as needed.

Here is the link for further reading and other useful examples.


如何使用matplotlib颜色图将NumPy数组转换为PIL图像

问题:如何使用matplotlib颜色图将NumPy数组转换为PIL图像

我有一个简单的问题,但找不到很好的解决方案。

我想获取一个代表灰度图像的NumPy 2D数组,并在应用一些matplotlib颜色图时将其转换为RGB PIL图像。

我可以使用以下pyplot.figure.figimage命令获得合理的PNG输出:

dpi = 100.0
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi
fig = plt.figure(figsize=(w,h), dpi=dpi)
fig.figimage(sub, cmap=cm.gist_earth)
plt.savefig('out.png')

尽管我可以修改它以获取所需的东西(可能使用StringIO可以获取PIL图像),但我想知道是否没有一种更简单的方法可以这样做,因为这似乎是图像可视化的一个非常自然的问题。假设是这样的:

colored_PIL_image = magic_function(array, cmap)

I have a simple problem, but I cannot find a good solution to it.

I want to take a NumPy 2D array which represents a grayscale image, and convert it to an RGB PIL image while applying some of the matplotlib colormaps.

I can get a reasonable PNG output by using the pyplot.figure.figimage command:

dpi = 100.0
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi
fig = plt.figure(figsize=(w,h), dpi=dpi)
fig.figimage(sub, cmap=cm.gist_earth)
plt.savefig('out.png')

Although I could adapt this to get what I want (probably using StringIO do get the PIL image), I wonder if there is not a simpler way to do that, since it seems to be a very natural problem of image visualization. Let’s say, something like this:

colored_PIL_image = magic_function(array, cmap)

回答 0

一行代码很忙,但是这里是:

  1. 首先,请确保您的NumPy数组myarray使用处的最大值进行了规范化1.0
  2. 将颜色表直接应用于myarray
  3. 重新调整0-255范围。
  4. 使用转换为整数np.uint8()
  5. 使用Image.fromarray()

这样就完成了:

from PIL import Image
from matplotlib import cm
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255))

plt.savefig()

im.save()

Quite a busy one-liner, but here it is:

  1. First ensure your NumPy array, myarray, is normalised with the max value at 1.0.
  2. Apply the colormap directly to myarray.
  3. Rescale to the 0-255 range.
  4. Convert to integers, using np.uint8().
  5. Use Image.fromarray().

And you’re done:

from PIL import Image
from matplotlib import cm
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255))

with plt.savefig():

with im.save():


回答 1

  • 输入= numpy_image
  • np.unit8->转换为整数
  • convert(’RGB’)->转换为RGB
  • Image.fromarray->返回图像对象

    from PIL import Image
    import numpy as np
    
    PIL_image = Image.fromarray(np.uint8(numpy_image)).convert('RGB')
    
    PIL_image = Image.fromarray(numpy_image.astype('uint8'), 'RGB')
  • input = numpy_image
  • np.unit8 -> converts to integers
  • convert(‘RGB’) -> converts to RGB
  • Image.fromarray -> returns an image object

    from PIL import Image
    import numpy as np
    
    PIL_image = Image.fromarray(np.uint8(numpy_image)).convert('RGB')
    
    PIL_image = Image.fromarray(numpy_image.astype('uint8'), 'RGB')
    

回答 2

即使应用了注释中提到的更改,接受的答案中描述的方法对我也不起作用。但是下面的简单代码有效:

import matplotlib.pyplot as plt
plt.imsave(filename, np_array, cmap='Greys')

np_array可以是2D数组,其值从0..1浮点型到o2 0..255 uint8,在这种情况下,它需要cmap。对于3D阵列,cmap将被忽略。

The method described in the accepted answer didn’t work for me even after applying changes mentioned in its comments. But the below simple code worked:

import matplotlib.pyplot as plt
plt.imsave(filename, np_array, cmap='Greys')

np_array could be either a 2D array with values from 0..1 floats o2 0..255 uint8, and in that case it needs cmap. For 3D arrays, cmap will be ignored.


Matplotlib透明线图

问题:Matplotlib透明线图

我在matplotlib中绘制了两个相似的轨迹,我想以部分透明的方式绘制每条线,以使红色(绘制的第二个)不会遮盖蓝色。

编辑:这是带有透明线的图像。

I am plotting two similar trajectories in matplotlib and I’d like to plot each of the lines with partial transparency so that the red (plotted second) doesn’t obscure the blue.

EDIT: Here’s the image with transparent lines.


回答 0

干净利落:

plt.plot(x, y, 'r-', alpha=0.7)

(我知道我没有添加任何新内容,但是简单的答案应该可见)。

Plain and simple:

plt.plot(x, y, 'r-', alpha=0.7)

(I know I add nothing new, but the straightforward answer should be visible).


回答 1

绘制完所有线条后,可以如下设置所有线条的透明度:

for l in fig_field.gca().lines:
    l.set_alpha(.7)

编辑:请在评论中查看乔的答案。

After I plotted all the lines, I was able to set the transparency of all of them as follows:

for l in fig_field.gca().lines:
    l.set_alpha(.7)

EDIT: please see Joe’s answer in the comments.


回答 2

这实际上取决于您要使用哪些函数来绘制线条,但是请尝试查看所使用的on是否采用alpha值并将其设置为0.5。如果那不起作用,请尝试获取线对象并直接设置其alpha值。

It really depends on what functions you’re using to plot the lines, but try see if the on you’re using takes an alpha value and set it to something like 0.5. If that doesn’t work, try get the line objects and set their alpha values directly.


使用matplotlib绘制水平线

问题:使用matplotlib绘制水平线

我使用样条插值法来平滑时间序列,并且还想在绘图中添加一条水平线。但是似乎有一个我无法控制的问题。任何帮助都会非常有帮助。这是我所拥有的:

annual = np.arange(1,21,1)
l = np.array(value_list) # a list with 20 values
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)
plt.plot(xs,spl(xs),'b')

plt.plot([0,len(xs)],[40,40],'r--',lw=2)
pylab.ylim([0,200])
plt.show()

问题似乎与我[0,len(xs)]对水平线图的使用有关。

I have used spline interpolation to smooth a time series and would also like to add a horizontal line to the plot. But there seems to be an issue that is out of my grips. Any assistance would be really helpful. Here is what I have:

annual = np.arange(1,21,1)
l = np.array(value_list) # a list with 20 values
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)
plt.plot(xs,spl(xs),'b')

plt.plot([0,len(xs)],[40,40],'r--',lw=2)
pylab.ylim([0,200])
plt.show()

problem seems to be with my use of [0,len(xs)] for horizontal line plotting.


回答 0

你是对的,我认为这使[0,len(xs)]你失望了。您将要重用原始的x轴变量,xs并使用另一个包含变量的相同长度的numpy数组对其进行绘制。

annual = np.arange(1,21,1)
l = np.array(value_list) # a list with 20 values
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)
plt.plot(xs,spl(xs),'b')

#####horizontal line
horiz_line_data = np.array([40 for i in xrange(len(xs))])
plt.plot(xs, horiz_line_data, 'r--') 
###########plt.plot([0,len(xs)],[40,40],'r--',lw=2)
pylab.ylim([0,200])
plt.show()

希望可以解决问题!

You are correct, I think the [0,len(xs)] is throwing you off. You’ll want to reuse the original x-axis variable xs and plot that with another numpy array of the same length that has your variable in it.

annual = np.arange(1,21,1)
l = np.array(value_list) # a list with 20 values
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)
plt.plot(xs,spl(xs),'b')

#####horizontal line
horiz_line_data = np.array([40 for i in xrange(len(xs))])
plt.plot(xs, horiz_line_data, 'r--') 
###########plt.plot([0,len(xs)],[40,40],'r--',lw=2)
pylab.ylim([0,200])
plt.show()

Hopefully that fixes the problem!


回答 1

您正在寻找axhline(水平轴线)。例如,以下代码将为您提供一条水平线y = 0.5

import matplotlib.pyplot as plt
plt.axhline(y=0.5, color='r', linestyle='-')
plt.show()

You’re looking for axhline (a horizontal axis line). For example, the following will give you a horizontal line at y = 0.5:

import matplotlib.pyplot as plt
plt.axhline(y=0.5, color='r', linestyle='-')
plt.show()


回答 2

如果要在轴上绘制一条水平线,也可以尝试ax.hlines()方法。您需要在数据坐标中指定y位置和xminxmax(即,您在x轴上的实际数据范围)。示例代码段为:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(1, 21, 200)
y = np.exp(-x)

fig, ax = plt.subplots()
ax.plot(x, y)
ax.hlines(y=0.2, xmin=4, xmax=20, linewidth=2, color='r')

plt.show()

上面的代码段将在处的轴上绘制一条水平线y=0.2。水平线的起点是x=4,终点为x=20。生成的图像是:

If you want to draw a horizontal line in the axes, you might also try ax.hlines() method. You need to specify y position and xmin and xmax in the data coordinate (i.e, your actual data range in the x-axis). A sample code snippet is:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(1, 21, 200)
y = np.exp(-x)

fig, ax = plt.subplots()
ax.plot(x, y)
ax.hlines(y=0.2, xmin=4, xmax=20, linewidth=2, color='r')

plt.show()

The snippet above will plot a horizontal line in the axes at y=0.2. The horizontal line starts at x=4 and ends at x=20. The generated image is:


回答 3

用途matplotlib.pyplot.hlines

  • y 可以作为单个位置传递: y=40
  • y 可以作为多个位置传递: y=[39, 40, 41]
  • 如果您在绘制的东西,如一个数字fig, ax = plt.subplots(),然后更换plt.hlinesplt.axhlineax.hlinesax.axhline分别。
  • matplotlib.pyplot.axhline只能绘制一个位置(例如y=40
import numpy as np
import matplotlib.pyplot as plt

xs = np.linspace(1, 21, 200)
plt.hlines(y=40, xmin=0, xmax=len(xs), colors='r', linestyles='--', lw=2)
plt.show()

Use matplotlib.pyplot.hlines:

  • Can plot multiple horizontal lines by passing a list to the y parameter.
  • y can be passed as a single location: y=40
  • y can be passed as multiple locations: y=[39, 40, 41]
  • If you’re a plotting a figure with something like fig, ax = plt.subplots(), then replace plt.hlines or plt.axhline with ax.hlines or ax.axhline, respectively.
  • matplotlib.pyplot.axhline can only plot a single location (e.g. y=40)

plt.plot

import numpy as np
import matplotlib.pyplot as plt

xs = np.linspace(1, 21, 200)

plt.figure(figsize=(6, 3))
plt.hlines(y=39.5, xmin=100, xmax=175, colors='aqua', linestyles='-', lw=2, label='Single Short Line')
plt.hlines(y=[39, 40, 41], xmin=[0, 25, 50], xmax=[len(xs)], colors='purple', linestyles='--', lw=2, label='Multiple Lines')
plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)

ax.plot

import numpy as np
import matplotlib.pyplot as plt

xs = np.linspace(1, 21, 200)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(6, 6))

ax1.hlines(y=40, xmin=0, xmax=len(xs), colors='r', linestyles='--', lw=2)
ax1.set_title('One Line')

ax2.hlines(y=[39, 40, 41], xmin=0, xmax=len(xs), colors='purple', linestyles='--', lw=2)
ax2.set_title('Multiple Lines')

plt.tight_layout()
plt.show()

Time Series Axis

  • xmin and xmax will accept a date like '2020-09-10' or datetime(2020, 9, 10)
    • xmin=datetime(2020, 9, 10), xmax=datetime(2020, 9, 10) + timedelta(days=3)
    • Given date = df.index[9], xmin=date, xmax=date + pd.Timedelta(days=3), where the index is a DatetimeIndex.
import pandas_datareader as web  # conda or pip install this; not part of pandas
import pandas as pd
import matplotlib.pyplot as plt

# get test data
df = web.DataReader('^gspc', data_source='yahoo', start='2020-09-01', end='2020-09-28').iloc[:, :2]

# plot dataframe
ax = df.plot(figsize=(9, 6), title='S&P 500', ylabel='Price')

# add horizontal line
ax.hlines(y=3450, xmin='2020-09-10', xmax='2020-09-17', color='purple', label='test')

ax.legend()
plt.show()

  • Sample time series data if web.DataReader doesn’t work.
data = {pd.Timestamp('2020-09-01 00:00:00'): {'High': 3528.03, 'Low': 3494.6}, pd.Timestamp('2020-09-02 00:00:00'): {'High': 3588.11, 'Low': 3535.23}, pd.Timestamp('2020-09-03 00:00:00'): {'High': 3564.85, 'Low': 3427.41}, pd.Timestamp('2020-09-04 00:00:00'): {'High': 3479.15, 'Low': 3349.63}, pd.Timestamp('2020-09-08 00:00:00'): {'High': 3379.97, 'Low': 3329.27}, pd.Timestamp('2020-09-09 00:00:00'): {'High': 3424.77, 'Low': 3366.84}, pd.Timestamp('2020-09-10 00:00:00'): {'High': 3425.55, 'Low': 3329.25}, pd.Timestamp('2020-09-11 00:00:00'): {'High': 3368.95, 'Low': 3310.47}, pd.Timestamp('2020-09-14 00:00:00'): {'High': 3402.93, 'Low': 3363.56}, pd.Timestamp('2020-09-15 00:00:00'): {'High': 3419.48, 'Low': 3389.25}, pd.Timestamp('2020-09-16 00:00:00'): {'High': 3428.92, 'Low': 3384.45}, pd.Timestamp('2020-09-17 00:00:00'): {'High': 3375.17, 'Low': 3328.82}, pd.Timestamp('2020-09-18 00:00:00'): {'High': 3362.27, 'Low': 3292.4}, pd.Timestamp('2020-09-21 00:00:00'): {'High': 3285.57, 'Low': 3229.1}, pd.Timestamp('2020-09-22 00:00:00'): {'High': 3320.31, 'Low': 3270.95}, pd.Timestamp('2020-09-23 00:00:00'): {'High': 3323.35, 'Low': 3232.57}, pd.Timestamp('2020-09-24 00:00:00'): {'High': 3278.7, 'Low': 3209.45}, pd.Timestamp('2020-09-25 00:00:00'): {'High': 3306.88, 'Low': 3228.44}, pd.Timestamp('2020-09-28 00:00:00'): {'High': 3360.74, 'Low': 3332.91}}

df = pd.DataFrame.from_dict(data, 'index')

回答 4

除了最upvoted答案在这里,你也可以使用链axhline打完电话后plotpandasDataFrame

import pandas as pd

(pd.DataFrame([1, 2, 3])
   .plot(kind='bar', color='orange')
   .axhline(y=1.5));

In addition to the most upvoted answer here, one can also chain axhline after calling plot on a pandas‘s DataFrame.

import pandas as pd

(pd.DataFrame([1, 2, 3])
   .plot(kind='bar', color='orange')
   .axhline(y=1.5));


回答 5

对于那些总是忘记命令的人来说,一个不错的简便方法axhline

plt.plot(x, [y]*len(x))

你的情况xs = xy = 40。如果len(x)大,则效率低下,您应该真正使用axhline

A nice and easy way for those people who always forget the command axhline is the following

plt.plot(x, [y]*len(x))

In your case xs = x and y = 40. If len(x) is large, then this becomes inefficient and you should really use axhline.


回答 6

您可以使用plt.grid绘制水平线。

import numpy as np
from matplotlib import pyplot as plt
from scipy.interpolate import UnivariateSpline
from matplotlib.ticker import LinearLocator

# your data here
annual = np.arange(1,21,1)
l = np.random.random(20)
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)

# plot your data
plt.plot(xs,spl(xs),'b')

# horizental line?
ax = plt.axes()
# three ticks:
ax.yaxis.set_major_locator(LinearLocator(3))
# plot grids only on y axis on major locations
plt.grid(True, which='major', axis='y')

# show
plt.show()

You can use plt.grid to draw a horizontal line.

import numpy as np
from matplotlib import pyplot as plt
from scipy.interpolate import UnivariateSpline
from matplotlib.ticker import LinearLocator

# your data here
annual = np.arange(1,21,1)
l = np.random.random(20)
spl = UnivariateSpline(annual,l)
xs = np.linspace(1,21,200)

# plot your data
plt.plot(xs,spl(xs),'b')

# horizental line?
ax = plt.axes()
# three ticks:
ax.yaxis.set_major_locator(LinearLocator(3))
# plot grids only on y axis on major locations
plt.grid(True, which='major', axis='y')

# show
plt.show()


Matplotlib:“未知投影’3d’”错误

问题:Matplotlib:“未知投影’3d’”错误

我刚安装了matplotlib,并尝试运行其中的示例脚本之一。但是我遇到了下面详述的错误。我究竟做错了什么?

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
cset = ax.contour(X, Y, Z, 16, extend3d=True)
ax.clabel(cset, fontsize=9, inline=1)

plt.show()

错误是

Traceback (most recent call last):
  File "<string>", line 245, in run_nodebug
  File "<module1>", line 5, in <module>
  File "C:\Python26\lib\site-packages\matplotlib\figure.py", line 945, in gca
    return self.add_subplot(111, **kwargs)
  File "C:\Python26\lib\site-packages\matplotlib\figure.py", line 677, in add_subplot
    projection_class = get_projection_class(projection)
  File "C:\Python26\lib\site-packages\matplotlib\projections\__init__.py", line 61, in get_projection_class
    raise ValueError("Unknown projection '%s'" % projection)
ValueError: Unknown projection '3d'

I just installed matplotlib and am trying to run one of there example scripts. However I run into the error detailed below. What am I doing wrong?

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
cset = ax.contour(X, Y, Z, 16, extend3d=True)
ax.clabel(cset, fontsize=9, inline=1)

plt.show()

The error is

Traceback (most recent call last):
  File "<string>", line 245, in run_nodebug
  File "<module1>", line 5, in <module>
  File "C:\Python26\lib\site-packages\matplotlib\figure.py", line 945, in gca
    return self.add_subplot(111, **kwargs)
  File "C:\Python26\lib\site-packages\matplotlib\figure.py", line 677, in add_subplot
    projection_class = get_projection_class(projection)
  File "C:\Python26\lib\site-packages\matplotlib\projections\__init__.py", line 61, in get_projection_class
    raise ValueError("Unknown projection '%s'" % projection)
ValueError: Unknown projection '3d'

回答 0

首先,我认为版本的mplot3D工作方式与当前版本的有所不同。matplotlib0.99matplotlib

您正在使用哪个版本?(尝试运行:python -c 'import matplotlib; print matplotlib."__version__")

我猜您正在运行的是version 0.99,在这种情况下,您需要使用稍微不同的语法或更新到的最新版本matplotlib

如果您正在运行version 0.99,请尝试执行此操作,而不要使用projection关键字参数:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d, Axes3D #<-- Note the capitalization! 
fig = plt.figure()

ax = Axes3D(fig) #<-- Note the difference from your original code...

X, Y, Z = axes3d.get_test_data(0.05)
cset = ax.contour(X, Y, Z, 16, extend3d=True)
ax.clabel(cset, fontsize=9, inline=1)
plt.show()

这应该工作在matplotlib 1.0.x,还有,不只是0.99

First off, I think mplot3D worked a bit differently in matplotlib version 0.99 than it does in the current version of matplotlib.

Which version are you using? (Try running: python -c 'import matplotlib; print matplotlib."__version__")

I’m guessing you’re running version 0.99, in which case you’ll need to either use a slightly different syntax or update to a more recent version of matplotlib.

If you’re running version 0.99, try doing this instead of using using the projection keyword argument:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d, Axes3D #<-- Note the capitalization! 
fig = plt.figure()

ax = Axes3D(fig) #<-- Note the difference from your original code...

X, Y, Z = axes3d.get_test_data(0.05)
cset = ax.contour(X, Y, Z, 16, extend3d=True)
ax.clabel(cset, fontsize=9, inline=1)
plt.show()

This should work in matplotlib 1.0.x, as well, not just 0.99.


回答 1

只是为了增加Joe Kington的答案(没有足够的声誉来发表评论),在http://matplotlib.org/examples/mplot3d/mixed_subplots_demo.html的文档中有一个很好的混合2d和3d绘图的例子,其中显示projection =’ 3d’与Axes3D导入结合使用。

from mpl_toolkits.mplot3d import Axes3D
...
ax = fig.add_subplot(2, 1, 1)
...
ax = fig.add_subplot(2, 1, 2, projection='3d')

实际上,只要存在Axes3D导入,

from mpl_toolkits.mplot3d import Axes3D
...
ax = fig.gca(projection='3d')

OP所使用的也可以。(已使用matplotlib 1.3.1版检查)

Just to add to Joe Kington’s answer (not enough reputation for a comment) there is a good example of mixing 2d and 3d plots in the documentation at http://matplotlib.org/examples/mplot3d/mixed_subplots_demo.html which shows projection=’3d’ working in combination with the Axes3D import.

from mpl_toolkits.mplot3d import Axes3D
...
ax = fig.add_subplot(2, 1, 1)
...
ax = fig.add_subplot(2, 1, 2, projection='3d')

In fact as long as the Axes3D import is present the line

from mpl_toolkits.mplot3d import Axes3D
...
ax = fig.gca(projection='3d')

as used by the OP also works. (checked with matplotlib version 1.3.1)


回答 2

整个导入mplot3d以使用“ projection =’3d’”。

在脚本顶部插入以下命令。它应该运行良好。

从mpl_toolkits导入mplot3d

Import mplot3d whole to use “projection = ‘3d'”.

Insert the command below in top of your script. It should run fine.

from mpl_toolkits import mplot3d

回答 3

我遇到了同样的问题,@ Joe Kington和@bvanlew的答案解决了我的问题。

但是当您使用pycharm并启用时,我应该添加更多信息auto import

格式化代码时,代码from mpl_toolkits.mplot3d import Axes3D会被pycharm自动删除。

所以,我的解决方案是

from mpl_toolkits.mplot3d import Axes3D
Axes3D = Axes3D  # pycharm auto import
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

而且效果很好!

I encounter the same problem, and @Joe Kington and @bvanlew’s answer solve my problem.

but I should add more infomation when you use pycharm and enable auto import.

when you format the code, the code from mpl_toolkits.mplot3d import Axes3D will auto remove by pycharm.

so, my solution is

from mpl_toolkits.mplot3d import Axes3D
Axes3D = Axes3D  # pycharm auto import
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

and it works well!


回答 4

试试这个:

import matplotlib.pyplot as plt
import seaborn as sns
from mpl_toolkits.mplot3d import axes3d

fig=plt.figure(figsize=(16,12.5))
ax=fig.add_subplot(2,2,1,projection="3d")

a=ax.scatter(Dataframe['bedrooms'],Dataframe['bathrooms'],Dataframe['floors'])
plt.plot(a)

Try this:

import matplotlib.pyplot as plt
import seaborn as sns
from mpl_toolkits.mplot3d import axes3d

fig=plt.figure(figsize=(16,12.5))
ax=fig.add_subplot(2,2,1,projection="3d")

a=ax.scatter(Dataframe['bedrooms'],Dataframe['bathrooms'],Dataframe['floors'])
plt.plot(a)

如何将单独的Pan​​das DataFrame绘制为子图?

问题:如何将单独的Pan​​das DataFrame绘制为子图?

我有一些Pandas DataFrame共享相同的价值规模,但是具有不同的列和索引。调用时df.plot(),会得到单独的绘图图像。我真正想要的是将它们与子图放置在同一块图上,但是不幸的是,我未能提出解决方案,并且希望获得一些帮助。

I have a few Pandas DataFrames sharing the same value scale, but having different columns and indices. When invoking df.plot(), I get separate plot images. what I really want is to have them all in the same plot as subplots, but I’m unfortunately failing to come up with a solution to how and would highly appreciate some help.


回答 0

您可以使用matplotlib手动创建子图,然后使用ax关键字在特定的子图上绘制数据框。例如,对于4个子图(2×2):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)

df1.plot(ax=axes[0,0])
df2.plot(ax=axes[0,1])
...

axes是一个包含不同子图轴的数组,您只需通过index即可访问一个axes
如果要共享x轴,则可以提供sharex=Trueplt.subplots

You can manually create the subplots with matplotlib, and then plot the dataframes on a specific subplot using the ax keyword. For example for 4 subplots (2×2):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)

df1.plot(ax=axes[0,0])
df2.plot(ax=axes[0,1])
...

Here axes is an array which holds the different subplot axes, and you can access one just by indexing axes.
If you want a shared x-axis, then you can provide sharex=True to plt.subplots.


回答 1

您可以看到例如 在演示joris答案的文档中。另外,从文档,您也可以设置subplots=Truelayout=(,)大熊猫内plot功能:

df.plot(subplots=True, layout=(1,2))

你也可以使用fig.add_subplot()这需要插曲电网参数,如221,222,223,224,等,在后描述这里。可以在此ipython笔记本中看到有关熊猫数据框(包括子图)的漂亮绘图示例。

You can see e.gs. in the documentation demonstrating joris answer. Also from the documentation, you could also set subplots=True and layout=(,) within the pandas plot function:

df.plot(subplots=True, layout=(1,2))

You could also use fig.add_subplot() which takes subplot grid parameters such as 221, 222, 223, 224, etc. as described in the post here. Nice examples of plot on pandas data frame, including subplots, can be seen in this ipython notebook.


回答 2

您可以使用熟悉的Matplotlib样式调用a figuresubplot,但是只需使用即可指定当前轴plt.gca()。一个例子:

plt.figure(1)
plt.subplot(2,2,1)
df.A.plot() #no need to specify for first axis
plt.subplot(2,2,2)
df.B.plot(ax=plt.gca())
plt.subplot(2,2,3)
df.C.plot(ax=plt.gca())

等等…

You can use the familiar Matplotlib style calling a figure and subplot, but you simply need to specify the current axis using plt.gca(). An example:

plt.figure(1)
plt.subplot(2,2,1)
df.A.plot() #no need to specify for first axis
plt.subplot(2,2,2)
df.B.plot(ax=plt.gca())
plt.subplot(2,2,3)
df.C.plot(ax=plt.gca())

etc…


回答 3

您可以使用matplotlib通过绘制所有数据框列表的简单技巧来绘制多个熊猫数据框的多个子图。然后使用for循环绘制子图。

工作代码:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# dataframe sample data
df1 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df2 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df3 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df4 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df5 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df6 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
#define number of rows and columns for subplots
nrow=3
ncol=2
# make a list of all dataframes 
df_list = [df1 ,df2, df3, df4, df5, df6]
fig, axes = plt.subplots(nrow, ncol)
# plot counter
count=0
for r in range(nrow):
    for c in range(ncol):
        df_list[count].plot(ax=axes[r,c])
        count=+1

使用此代码,您可以在任何配置中绘制子图。您只需要定义行nrow数和列数即可ncol。另外,您需要列出df_list要绘制的数据框。

You can plot multiple subplots of multiple pandas data frames using matplotlib with a simple trick of making a list of all data frame. Then using the for loop for plotting subplots.

Working code:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# dataframe sample data
df1 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df2 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df3 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df4 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df5 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df6 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
#define number of rows and columns for subplots
nrow=3
ncol=2
# make a list of all dataframes 
df_list = [df1 ,df2, df3, df4, df5, df6]
fig, axes = plt.subplots(nrow, ncol)
# plot counter
count=0
for r in range(nrow):
    for c in range(ncol):
        df_list[count].plot(ax=axes[r,c])
        count=+1

Using this code you can plot subplots in any configuration. You need to just define number of rows nrow and number of columns ncol. Also, you need to make list of data frames df_list which you wanted to plot.


回答 4

您可以使用此:

fig = plt.figure()
ax = fig.add_subplot(221)
plt.plot(x,y)

ax = fig.add_subplot(222)
plt.plot(x,z)
...

plt.show()

You can use this:

fig = plt.figure()
ax = fig.add_subplot(221)
plt.plot(x,y)

ax = fig.add_subplot(222)
plt.plot(x,z)
...

plt.show()

回答 5

您可能根本不需要使用熊猫。这是猫的频率的matplotlib图:

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

f, axes = plt.subplots(2, 1)
for c, i in enumerate(axes):
  axes[c].plot(x, y)
  axes[c].set_title('cats')
plt.tight_layout()

You may not need to use Pandas at all. Here’s a matplotlib plot of cat frequencies:

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

f, axes = plt.subplots(2, 1)
for c, i in enumerate(axes):
  axes[c].plot(x, y)
  axes[c].set_title('cats')
plt.tight_layout()

回答 6

以上面的@joris响应为基础,如果您已经建立了对该子图的引用,则也可以使用该引用。例如,

ax1 = plt.subplot2grid((50,100), (0, 0), colspan=20, rowspan=10)
...

df.plot.barh(ax=ax1, stacked=True)

Building on @joris response above, if you have already established a reference to the subplot, you can use the reference as well. For example,

ax1 = plt.subplot2grid((50,100), (0, 0), colspan=20, rowspan=10)
...

df.plot.barh(ax=ax1, stacked=True)

回答 7

如何从具有长(整洁)数据的数据帧字典中创建多个图

  • 假设条件

    • 有一个包含多个整齐数据框架的字典
      • 通过读取文件创建
      • 通过将单个数据帧分为多个数据帧来创建
    • 类别cat可能重叠,但是所有数据框可能不包含的所有值cat
    • hue='cat'
  • 因为要遍历数据帧,所以不能保证每个图的颜色都相同

    • 需要根据'cat'所有数据框的唯一值创建自定义颜色图
    • 由于颜色相同,因此在图的侧面放置一个图例,而不要在每个图上都放置图例

导入和综合数据

import pandas as pd
import numpy as np  # used for random data
import random  # used for random data
import matplotlib.pyplot as plt
from matplotlib.patches import Patch  # for custom legend
import seaborn as sns
import math import ceil  # determine correct number of subplot


# synthetic data
df_dict = dict()
for i in range(1, 7):
    np.random.seed(i)
    random.seed(i)
    data_length = 100
    data = {'cat': [random.choice(['A', 'B', 'C']) for _ in range(data_length)],
            'x': np.random.rand(data_length),
            'y': np.random.rand(data_length)}
    df_dict[i] = pd.DataFrame(data)


# display(df_dict[1].head())

  cat         x         y
0   A  0.417022  0.326645
1   C  0.720324  0.527058
2   A  0.000114  0.885942
3   B  0.302333  0.357270
4   A  0.146756  0.908535

创建颜色映射并绘制

# create color mapping based on all unique values of cat
unique_cat = {cat for v in df_dict.values() for cat in v.cat.unique()}  # get unique cats
colors = sns.color_palette('husl', n_colors=len(unique_cat))  # get a number of colors
cmap = dict(zip(unique_cat, colors))  # zip values to colors

# iterate through dictionary and plot
col_nums = 3  # how many plots per row
row_nums = math.ceil(len(df_dict) / col_nums)  # how many rows of plots
plt.figure(figsize=(10, 5))  # change the figure size as needed
for i, (k, v) in enumerate(df_dict.items(), 1):
    plt.subplot(row_nums, col_nums, i)  # create subplots
    p = sns.scatterplot(data=v, x='x', y='y', hue='cat', palette=cmap)
    p.legend_.remove()  # remove the individual plot legends
    plt.title(f'DataFrame: {k}')

plt.tight_layout()
# create legend from cmap
patches = [Patch(color=v, label=k) for k, v in cmap.items()]
# place legend outside of plot; change the right bbox value to move the legend up or down
plt.legend(handles=patches, bbox_to_anchor=(1.06, 1.2), loc='center left', borderaxespad=0)
plt.show()

How to create multiple plots from a dictionary of dataframes with long (tidy) data

  • Assumptions

    • There is a dictionary of multiple dataframes of tidy data
      • Created by reading in from files
      • Created by separating a single dataframe into multiple dataframes
    • The categories, cat, may be overlapping, but all dataframes may not contain all values of cat
    • hue='cat'
  • Because dataframes are being iterated through, there’s not guarantee that colors will be mapped the same for each plot

    • A custom color map needs to be created from the unique 'cat' values for all the dataframes
    • Since the colors will be the same, place one legend to the side of the plots, instead of a legend in every plot

Imports and synthetic data

import pandas as pd
import numpy as np  # used for random data
import random  # used for random data
import matplotlib.pyplot as plt
from matplotlib.patches import Patch  # for custom legend
import seaborn as sns
import math import ceil  # determine correct number of subplot


# synthetic data
df_dict = dict()
for i in range(1, 7):
    np.random.seed(i)
    random.seed(i)
    data_length = 100
    data = {'cat': [random.choice(['A', 'B', 'C']) for _ in range(data_length)],
            'x': np.random.rand(data_length),
            'y': np.random.rand(data_length)}
    df_dict[i] = pd.DataFrame(data)


# display(df_dict[1].head())

  cat         x         y
0   A  0.417022  0.326645
1   C  0.720324  0.527058
2   A  0.000114  0.885942
3   B  0.302333  0.357270
4   A  0.146756  0.908535

Create color mappings and plot

# create color mapping based on all unique values of cat
unique_cat = {cat for v in df_dict.values() for cat in v.cat.unique()}  # get unique cats
colors = sns.color_palette('husl', n_colors=len(unique_cat))  # get a number of colors
cmap = dict(zip(unique_cat, colors))  # zip values to colors

# iterate through dictionary and plot
col_nums = 3  # how many plots per row
row_nums = math.ceil(len(df_dict) / col_nums)  # how many rows of plots
plt.figure(figsize=(10, 5))  # change the figure size as needed
for i, (k, v) in enumerate(df_dict.items(), 1):
    plt.subplot(row_nums, col_nums, i)  # create subplots
    p = sns.scatterplot(data=v, x='x', y='y', hue='cat', palette=cmap)
    p.legend_.remove()  # remove the individual plot legends
    plt.title(f'DataFrame: {k}')

plt.tight_layout()
# create legend from cmap
patches = [Patch(color=v, label=k) for k, v in cmap.items()]
# place legend outside of plot; change the right bbox value to move the legend up or down
plt.legend(handles=patches, bbox_to_anchor=(1.06, 1.2), loc='center left', borderaxespad=0)
plt.show()


如何在Python matplotlib中使x轴和y轴的比例相等?

问题:如何在Python matplotlib中使x轴和y轴的比例相等?

我希望在方形图上画线。

天秤x-axisy-axis应该是相同的。

例如x的范围是0到10,在屏幕上是10厘米。y也必须在0到10的范围内,并且也必须是10 cm。

即使我迷失了窗口大小,也必须保持正方形。

目前,我的图形与窗口大小一起缩放。

我该如何实现?

更新:

我尝试了以下操作,但没有成功。

plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.axis('equal')

I wish to draw lines on a square graph.

The scales of x-axis and y-axis should be the same.

e.g. x ranges from 0 to 10 and it is 10cm on the screen. y has to also range from 0 to 10 and has to be also 10 cm.

The square shape has to be maintained, even if I mess around with the window size.

Currently, my graph scales together with the window size.

How may I achieve this?

UPDATE:

I tried the following, but it did not work.

plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.axis('equal')

回答 0

您需要对api进行更深入的研究:

from matplotlib import pyplot as plt
plt.plot(range(5))
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.gca().set_aspect('equal', adjustable='box')
plt.draw()

set_aspect的文档

You need to dig a bit deeper into the api to do this:

from matplotlib import pyplot as plt
plt.plot(range(5))
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.gca().set_aspect('equal', adjustable='box')
plt.draw()

doc for set_aspect


回答 1

plt.axis('scaled')

对我来说效果很好。

plt.axis('scaled')

works well for me.


回答 2

尝试类似的方法:

import pylab as p
p.plot(x,y)
p.axis('equal')
p.show()

Try something like:

import pylab as p
p.plot(x,y)
p.axis('equal')
p.show()

回答 3

文档plt.axis()。这个:

plt.axis('equal')

不起作用,因为它更改了轴的界限以使圆看起来是圆形。您想要的是:

plt.axis('square')

这将创建具有相等轴的正方形图。

See the documentation on plt.axis(). This:

plt.axis('equal')

doesn’t work because it changes the limits of the axis to make circles appear circular. What you want is:

plt.axis('square')

This creates a square plot with equal axes.