标签归档:graph

相当于D3.js的Python

问题:相当于D3.js的Python

谁能推荐一个可以进行交互式图形可视化的Python库?

我特别想要d3.js之类的东西,python理想情况下,它也是3D的。

我看了看:

  • NetworkX-仅做Matplotlib图,而那些图似乎是2D的。我没有看到任何形式的交互性,例如d3.js提供的交互性。
  • graph-tool-它仅执行2D绘图,并且交互式图形非常慢。

Can anyone recommend a Python library that can do interactive graph visualization?

I specifically want something like d3.js but for python and ideally it would be 3D as well.

I have looked at:

  • NetworkX – it only does Matplotlib plots and those seem to be 2D. I didn’t see any sort of interactiveness, like one that d3.js gives, such as pulling nodes around.
  • graph-tool – it does only 2D plots and has very slow interactive graphs.

回答 0

您可以使用d3py一个python模块,该模块生成嵌入d3.js脚本的xml页面。例如 :

import d3py
import networkx as nx

import logging
logging.basicConfig(level=logging.DEBUG)

G = nx.Graph()
G.add_edge(1,2)
G.add_edge(1,3)
G.add_edge(3,2)
G.add_edge(3,4)
G.add_edge(4,2)

# use 'with' if you are writing a script and want to serve this up forever
with d3py.NetworkXFigure(G, width=500, height=500) as p:
    p += d3py.ForceLayout()
    p.show()

You could use d3py a python module that generate xml pages embedding d3.js script. For example :

import d3py
import networkx as nx

import logging
logging.basicConfig(level=logging.DEBUG)

G = nx.Graph()
G.add_edge(1,2)
G.add_edge(1,3)
G.add_edge(3,2)
G.add_edge(3,4)
G.add_edge(4,2)

# use 'with' if you are writing a script and want to serve this up forever
with d3py.NetworkXFigure(G, width=500, height=500) as p:
    p += d3py.ForceLayout()
    p.show()

回答 1

全面支持交互式2D和3D图形。图形使用D3.js呈现,并且可以使用Python APImatplotlib适用于Python的ggplotSeabornprettyplotlibpandas创建。您可以缩放,平移,打开和关闭轨迹,以及在悬停时查看数据。可以将图表嵌入HTML,应用程序,仪表板和IPython笔记本中。以下是显示互动性的温度图。有关更多示例,请参见IPython Notebooks 教程库。



文档提供了受支持的绘图类型和代码段的示例。





专门针对您的问题,您还可以从NetworkX 进行交互式绘图



对于使用Python进行3D绘图,您可以进行类似交互的3D散点图,线图和曲面图。用WebGL绘制图。例如,查看英国掉期利率的3D图



披露:我在Plotly团队中。

Plotly supports interactive 2D and 3D graphing. Graphs are rendered with D3.js and can be created with a Python API, matplotlib, ggplot for Python, Seaborn, prettyplotlib, and pandas. You can zoom, pan, toggle traces on and off, and see data on the hover. Plots can be embedded in HTML, apps, dashboards, and IPython Notebooks. Below is a temperature graph showing interactivity. See the gallery of IPython Notebooks tutorials for more examples.



The docs provides examples of supported plot types and code snippets.





Specifically to your question, you can also make interactive plots from NetworkX.



For 3D plotting with Python, you can make 3D scatter, line, and surface plots that are similarly interactive. Plots are rendered with WebGL. For example, see a 3D graph of UK Swap rates.



Disclosure: I’m on the Plotly team.


回答 2

你看过文森特了吗?Vincent将Python数据对象转换为Vega可视化语法。Vega是基于D3的高级可视化工具。与D3py相比,文森特仓库已更新。尽管这些示例都是静态D3。

更多信息:


可以在Ipython中查看图形,只需添加以下代码

vincent.core.initialize_notebook()

或输出到JSON,您可以在Vega在线编辑器(http://trifacta.github.io/vega/editor/)中查看JSON输出图,或在本地的Python服务器上查看它们。有关查看的更多信息,请参见上面的pypi链接。

不知道什么时候,但是Pandas软件包应该在某个时候集成D3。 http://pandas.pydata.org/developers.html

Bokeh是一个Python可视化库,支持交互式可视化。它的主要输出后端是HTML5 Canvas,并使用客户端/服务器模型。

示例:http : //continuumio.github.io/bokehjs/

Have you looked at vincent? Vincent takes Python data objects and converts them to Vega visualization grammar. Vega is a higher-level visualization tool built on top of D3. As compared to D3py, the vincent repo has been updated more recently. Though the examples are all static D3.

more info:


The graphs can be viewed in Ipython, just add this code

vincent.core.initialize_notebook()

Or output to JSON where you can view the JSON output graph in the Vega online editor (http://trifacta.github.io/vega/editor/) or view them on your Python server locally. More info on viewing can be found in the pypi link above.

Not sure when, but the Pandas package should have D3 integration at some point. http://pandas.pydata.org/developers.html

Bokeh is a Python visualization library that supports interactive visualization. Its primary output backend is HTML5 Canvas and uses client/server model.

examples: http://continuumio.github.io/bokehjs/


回答 3

我使用的一种方法(在这里进行描述:通过Scraperwiki和networkx从OpenCorporates Data获得GEXF和JSON中的联合导演网络数据文件)运行如下:

  • 使用networkx生成网络表示
  • 将网络导出为JSON文件
  • 将该JSON导入到d3.js中。(networkx可以导出d3.js可以导入的树和图/网络表示形式)。

networkx JSON出口国采取以下形式:

from networkx.readwrite import json_graph
import json
print json.dumps(json_graph.node_link_data(G))

或者,您可以将网络导出GEXF XML文件,然后将该表示形式导入sigma.js Javascript可视化库。

from xml.etree.cElementTree import tostring
writer=gf.GEXFWriter(encoding='utf-8',prettyprint=True,version='1.1draft')
writer.add_graph(G)
print tostring(writer.xml)

One recipe that I have used (described here: Co-Director Network Data Files in GEXF and JSON from OpenCorporates Data via Scraperwiki and networkx ) runs as follows:

  • generate a network representation using networkx
  • export the network as a JSON file
  • import that JSON into to d3.js. (networkx can export both the tree and graph/network representations that d3.js can import).

The networkx JSON exporter takes the form:

from networkx.readwrite import json_graph
import json
print json.dumps(json_graph.node_link_data(G))

Alternatively you can export the network as a GEXF XML file and then import this representation into the sigma.js Javascript visualisation library.

from xml.etree.cElementTree import tostring
writer=gf.GEXFWriter(encoding='utf-8',prettyprint=True,version='1.1draft')
writer.add_graph(G)
print tostring(writer.xml)

回答 4

另一个选择是bokeh,它刚发布到0.3版。

Another option is bokeh which just went to version 0.3.


回答 5

对于那些推荐pyd3的人,它不再处于积极开发中,并为您指明vincent。文森特也不再积极开发,建议使用Altair

因此,如果您要使用Python D3,请使用altair。

For those who recommended pyd3, it is no longer under active development and points you to vincent. vincent is also no longer under active development and recommends using altair.

So if you want a pythonic d3, use altair.


回答 6


回答 7

查看python-nvd3。它是nvd3的python包装器。看起来比d3.py更酷,并且还具有更多图表选项。

Check out python-nvd3. It is a python wrapper for nvd3. Looks cooler than d3.py and also has more chart options.


回答 8

我建议使用mpld3,它结合了D3js javascript可视化和python的matplotlib。

安装和使用非常简单,并且包含一些很棒的插件和交互式内容。

http://mpld3.github.io/

I would suggest using mpld3 which combines D3js javascript visualizations with matplotlib of python.

The installation and usage is really simple and it has some cool plugins and interactive stuffs.

http://mpld3.github.io/


回答 9

情节可以为您做一些很酷的事情

https://plot.ly/

生成高度交互式的图形,可以使用其离线API轻松将其与私有服务器或网站的HTML页面一起嵌入。

更新: 我注意到它的3D绘图功能肯定,因为2D图形很棒

Plotly can do some cool stuffs for you

https://plot.ly/

Produces highly interactive graphs that can be easily embedded withing the HTML pages for your private server or website using its off line API.

Update: I am note sure about its 3D plotting capabilities, for 2D graphs is awesome Thanks


回答 10

您还可以选择序列化数据,然后在D3.js中将其可视化,如下所示: 使用Python和Pandas创建D3强制定向网络图Jupyter笔记本也随附!)

这是要点。您可以使用以下格式序列化图形数据:

import json
json_data = {
  "nodes":[
    {"name":"Myriel","group":1},
    {"name":"Napoleon","group":1},
    {"name":"Mlle.Baptistine","group":1},
    {"name":"Mme.Magloire","group":1},
    {"name":"CountessdeLo","group":1},
  ],
  "links":[
    {"source":1,"target":0,"value":1},
    {"source":2,"target":0,"value":8},
    {"source":3,"target":0,"value":10},
    {"source":3,"target":2,"value":6},
    {"source":4,"target":0,"value":1},
    {"source":5,"target":0,"value":1},
  ]
}
filename_out = 'graph_data.json'
json_out = open(filename_out,'w')
json_out.write(json_data)
json_out.close()

然后使用d3.js加载数据:

d3.json("pcap_export.json", drawGraph);

对于常规 drawGraph我将向您推荐该链接。

You can also choose to serialize your data and then visualize it in D3.js, as done here: Use Python & Pandas to Create a D3 Force Directed Network Diagram (It comes with a jupyter notebook as well!)

Here is the gist. You serialize your graph data in this format:

import json
json_data = {
  "nodes":[
    {"name":"Myriel","group":1},
    {"name":"Napoleon","group":1},
    {"name":"Mlle.Baptistine","group":1},
    {"name":"Mme.Magloire","group":1},
    {"name":"CountessdeLo","group":1},
  ],
  "links":[
    {"source":1,"target":0,"value":1},
    {"source":2,"target":0,"value":8},
    {"source":3,"target":0,"value":10},
    {"source":3,"target":2,"value":6},
    {"source":4,"target":0,"value":1},
    {"source":5,"target":0,"value":1},
  ]
}
filename_out = 'graph_data.json'
json_out = open(filename_out,'w')
json_out.write(json_data)
json_out.close()

Then you load the data in with d3.js:

d3.json("pcap_export.json", drawGraph);

For the routine drawGraph I refer you to the link, however.


回答 11

NetworkX有一个有趣的Java移植端口,可以完成您想要的操作。参见http://felix-kling.de/JSNetworkX/

There is an interesting port of NetworkX to Javascript that might do what you want. See http://felix-kling.de/JSNetworkX/


回答 12

看到:

是否有一个好的交互式3D图形库?

可接受的答案建议使用以下程序,该程序显然具有python绑定:http : //ubietylab.net/ubigraph/

编辑

我不确定NetworkX的交互性,但是您绝对可以制作3D图形。图库中至少有一个示例:

http://networkx.lanl.gov/examples/drawing/edge_colormap.html

还有“示例”中的另一个示例。但是,这一项要求您拥有Mayavi。

http://networkx.lanl.gov/examples/3d_drawing/mayavi2_spring.html

See:

Is there a good interactive 3D graph library out there?

The accepted answer suggests the following program, which apparently has python bindings: http://ubietylab.net/ubigraph/

Edit

I’m not sure about the interactivity of NetworkX, but you can definitely make 3D graphs. There is at least one example in the gallery:

http://networkx.lanl.gov/examples/drawing/edge_colormap.html

And another example in the ‘examples’. This one, however, requires that you have Mayavi.

http://networkx.lanl.gov/examples/3d_drawing/mayavi2_spring.html


回答 13

我有一个很好的示例,可以在这里使用Python自动生成D3.js网络图:http : //brandonrose.org/ner2sna

很棒的事情是,您最终获得了自动生成的HTML和JS,并且可以将交互式D3图表嵌入到具有IFrame的笔记本中

I’ve got a good example of automatically generating D3.js network diagrams using Python here: http://brandonrose.org/ner2sna

The cool thing is that you end up with auto-generated HTML and JS and can embed the interactive D3 chart in a notebook with an IFrame


回答 14

该库d3graph将从python内部构建一个力控d3图。您可以根据边缘权重“破坏”网络,并将鼠标悬停在节点上以获取更多信息。双击节点将聚焦于该节点及其连接的边缘。

pip install d3graph

例:

source = ['node A','node F','node B','node B','node B','node A','node C','node Z']
target = ['node F','node B','node J','node F','node F','node M','node M','node A']
weight = [5.56, 0.5, 0.64, 0.23, 0.9,3.28,0.5,0.45]

# Import library
from d3graph import d3graph, vec2adjmat

# Convert to adjacency matrix
adjmat = vec2adjmat(source, target, weight=weight)
print(adjmat)
# target  node A  node B  node F  node J  node M  node C  node Z
# source                                                        
# node A    0.00     0.0    5.56    0.00    3.28     0.0     0.0
# node B    0.00     0.0    1.13    0.64    0.00     0.0     0.0
# node F    0.00     0.5    0.00    0.00    0.00     0.0     0.0
# node J    0.00     0.0    0.00    0.00    0.00     0.0     0.0
# node M    0.00     0.0    0.00    0.00    0.00     0.0     0.0
# node C    0.00     0.0    0.00    0.00    0.50     0.0     0.0
# node Z    0.45     0.0    0.00    0.00    0.00     0.0     0.0

# Example A: simple interactive network
out = d3graph(adjmat)

# Example B: Color nodes
out = d3graph(adjmat, node_color=adjmat.columns.values)

# Example C: include node size
node_size = [10,20,10,10,15,10,5]
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size)

# Example D: include node-edge-size
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], cmap='Set2')

# Example E: include node-edge color
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF')

# Example F: Change colormap
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF', cmap='Set2')

# Example H: Include directed links. Arrows are set from source -> target
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF', cmap='Set2', directed=True)

泰坦尼克号案例的互动示例可以在这里找到:https : //erdogant.github.io/docs/d3graph/titanic_example/index.html https://erdogant.github.io/hnet/pages/html/Use%20Cases .html

The library d3graph will build a force-directed d3-graph from within python. You can “break” the network based on the edge weight, and hover over the nodes for more information. Double click on a node will focus on the node and its connected edges.

pip install d3graph

Example:

source = ['node A','node F','node B','node B','node B','node A','node C','node Z']
target = ['node F','node B','node J','node F','node F','node M','node M','node A']
weight = [5.56, 0.5, 0.64, 0.23, 0.9,3.28,0.5,0.45]

# Import library
from d3graph import d3graph, vec2adjmat

# Convert to adjacency matrix
adjmat = vec2adjmat(source, target, weight=weight)
print(adjmat)
# target  node A  node B  node F  node J  node M  node C  node Z
# source                                                        
# node A    0.00     0.0    5.56    0.00    3.28     0.0     0.0
# node B    0.00     0.0    1.13    0.64    0.00     0.0     0.0
# node F    0.00     0.5    0.00    0.00    0.00     0.0     0.0
# node J    0.00     0.0    0.00    0.00    0.00     0.0     0.0
# node M    0.00     0.0    0.00    0.00    0.00     0.0     0.0
# node C    0.00     0.0    0.00    0.00    0.50     0.0     0.0
# node Z    0.45     0.0    0.00    0.00    0.00     0.0     0.0

# Example A: simple interactive network
out = d3graph(adjmat)

# Example B: Color nodes
out = d3graph(adjmat, node_color=adjmat.columns.values)

# Example C: include node size
node_size = [10,20,10,10,15,10,5]
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size)

# Example D: include node-edge-size
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], cmap='Set2')

# Example E: include node-edge color
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF')

# Example F: Change colormap
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF', cmap='Set2')

# Example H: Include directed links. Arrows are set from source -> target
out = d3graph(adjmat, node_color=adjmat.columns.values, node_size=node_size, node_size_edge=node_size[::-1], node_color_edge='#00FFFF', cmap='Set2', directed=True)

Interactive example from the titanic-case can be found here: https://erdogant.github.io/docs/d3graph/titanic_example/index.html https://erdogant.github.io/hnet/pages/html/Use%20Cases.html


在Matplotlib中,如何在同一图形上绘制多个函数?

问题:在Matplotlib中,如何在同一图形上绘制多个函数?

我如何可以绘制以下3个功能(即sincos并增加),在域t,在相同的数字?

from numpy import *
import math
import matplotlib.pyplot as plt

t = linspace(0, 2*math.pi, 400)

a = sin(t)
b = cos(t)
c = a + b

How can I plot the following 3 functions (i.e. sin, cos and the addition), on the domain t, in the same figure?

from numpy import *
import math
import matplotlib.pyplot as plt

t = linspace(0, 2*math.pi, 400)

a = sin(t)
b = cos(t)
c = a + b

回答 0

要在同一图形上绘制多个图形,您必须执行以下操作:

from numpy import *
import math
import matplotlib.pyplot as plt

t = linspace(0, 2*math.pi, 400)
a = sin(t)
b = cos(t)
c = a + b

plt.plot(t, a, 'r') # plotting t, a separately 
plt.plot(t, b, 'b') # plotting t, b separately 
plt.plot(t, c, 'g') # plotting t, c separately 
plt.show()

To plot multiple graphs on the same figure you will have to do:

from numpy import *
import math
import matplotlib.pyplot as plt

t = linspace(0, 2*math.pi, 400)
a = sin(t)
b = cos(t)
c = a + b

plt.plot(t, a, 'r') # plotting t, a separately 
plt.plot(t, b, 'b') # plotting t, b separately 
plt.plot(t, c, 'g') # plotting t, c separately 
plt.show()


回答 1

也许是更Python化的方式。

from numpy import *
import math
import matplotlib.pyplot as plt

t = linspace(0,2*math.pi,400)
a = sin(t)
b = cos(t)
c = a + b

plt.plot(t, a, t, b, t, c)
plt.show()

Perhaps a more pythonic way of doing so.

from numpy import *
import math
import matplotlib.pyplot as plt

t = linspace(0,2*math.pi,400)
a = sin(t)
b = cos(t)
c = a + b

plt.plot(t, a, t, b, t, c)
plt.show()


回答 2

只需使用功能plot如下

figure()
...
plot(t, a)
plot(t, b)
plot(t, c)

Just use the function plot as follows

figure()
...
plot(t, a)
plot(t, b)
plot(t, c)

在Python中表示图(数据结构)

问题:在Python中表示图(数据结构)

如何用Python巧妙地表示图形?(从头开始,即没有库!)哪种数据结构(例如dicts / tuples / dict(tuples))既快速又具有存储效率?必须能够对它执行各种图形操作。 如前所述,各种图形表示可能会有所帮助。如何在Python中实现它们?至于图书馆,这个问题有很好的答案。





How can one neatly represent a graph in Python? (Starting from scratch i.e. no libraries!)
What data structure (e.g. dicts/tuples/dict(tuples)) will be fast but also memory efficient?
One must be able to do various graph operations on it.

As pointed out, the various graph representations might help. How does one go about implementing them in Python?

As for the libraries, this question has quite good answers.


回答 0

即使这是一个有点老的问题,我还是想为遇到问题的任何人提供一个切实可行的答案。

假设您以元组列表的形式获取连接的输入数据,如下所示:

[('A', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('E', 'F'), ('F', 'C')]

我发现对于Python中的图形最有用和最有效的数据结构是集合的决定。这将是我们GraphClass的基础结构。您还必须知道这些连接是弧形(定向,以一种方式连接)还是边缘(无定向,以两种方式连接)。我们将通过directed向该Graph.__init__方法添加参数来处理该问题。我们还将添加一些其他有用的方法。

import pprint
from collections import defaultdict


class Graph(object):
    """ Graph data structure, undirected by default. """

    def __init__(self, connections, directed=False):
        self._graph = defaultdict(set)
        self._directed = directed
        self.add_connections(connections)

    def add_connections(self, connections):
        """ Add connections (list of tuple pairs) to graph """

        for node1, node2 in connections:
            self.add(node1, node2)

    def add(self, node1, node2):
        """ Add connection between node1 and node2 """

        self._graph[node1].add(node2)
        if not self._directed:
            self._graph[node2].add(node1)

    def remove(self, node):
        """ Remove all references to node """

        for n, cxns in self._graph.items():  # python3: items(); python2: iteritems()
            try:
                cxns.remove(node)
            except KeyError:
                pass
        try:
            del self._graph[node]
        except KeyError:
            pass

    def is_connected(self, node1, node2):
        """ Is node1 directly connected to node2 """

        return node1 in self._graph and node2 in self._graph[node1]

    def find_path(self, node1, node2, path=[]):
        """ Find any path between node1 and node2 (may not be shortest) """

        path = path + [node1]
        if node1 == node2:
            return path
        if node1 not in self._graph:
            return None
        for node in self._graph[node1]:
            if node not in path:
                new_path = self.find_path(node, node2, path)
                if new_path:
                    return new_path
        return None

    def __str__(self):
        return '{}({})'.format(self.__class__.__name__, dict(self._graph))

我将其作为创建读者find_shortest_path和其他方法的“读者练习” 。

让我们来看一下这个动作…

>>> connections = [('A', 'B'), ('B', 'C'), ('B', 'D'),
                   ('C', 'D'), ('E', 'F'), ('F', 'C')]
>>> g = Graph(connections, directed=True)
>>> pretty_print = pprint.PrettyPrinter()
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'C'},
 'C': {'D'},
 'E': {'F'},
 'F': {'C'}}

>>> g = Graph(connections)  # undirected
>>> pretty_print = pprint.PrettyPrinter()
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'A', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'B'},
 'E': {'F'},
 'F': {'E', 'C'}}

>>> g.add('E', 'D')
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'A', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'}}

>>> g.remove('A')
>>> pretty_print.pprint(g._graph)
{'B': {'D', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'}}

>>> g.add('G', 'B')
>>> pretty_print.pprint(g._graph)
{'B': {'D', 'G', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'},
 'G': {'B'}}

>>> g.find_path('G', 'E')
['G', 'B', 'D', 'C', 'F', 'E']

Even though this is a somewhat old question, I thought I’d give a practical answer for anyone stumbling across this.

Let’s say you get your input data for your connections as a list of tuples like so:

[('A', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('E', 'F'), ('F', 'C')]

The data structure I’ve found to be most useful and efficient for graphs in Python is a dict of sets. This will be the underlying structure for our Graph class. You also have to know if these connections are arcs (directed, connect one way) or edges (undirected, connect both ways). We’ll handle that by adding a directed parameter to the Graph.__init__ method. We’ll also add some other helpful methods.

import pprint
from collections import defaultdict


class Graph(object):
    """ Graph data structure, undirected by default. """

    def __init__(self, connections, directed=False):
        self._graph = defaultdict(set)
        self._directed = directed
        self.add_connections(connections)

    def add_connections(self, connections):
        """ Add connections (list of tuple pairs) to graph """

        for node1, node2 in connections:
            self.add(node1, node2)

    def add(self, node1, node2):
        """ Add connection between node1 and node2 """

        self._graph[node1].add(node2)
        if not self._directed:
            self._graph[node2].add(node1)

    def remove(self, node):
        """ Remove all references to node """

        for n, cxns in self._graph.items():  # python3: items(); python2: iteritems()
            try:
                cxns.remove(node)
            except KeyError:
                pass
        try:
            del self._graph[node]
        except KeyError:
            pass

    def is_connected(self, node1, node2):
        """ Is node1 directly connected to node2 """

        return node1 in self._graph and node2 in self._graph[node1]

    def find_path(self, node1, node2, path=[]):
        """ Find any path between node1 and node2 (may not be shortest) """

        path = path + [node1]
        if node1 == node2:
            return path
        if node1 not in self._graph:
            return None
        for node in self._graph[node1]:
            if node not in path:
                new_path = self.find_path(node, node2, path)
                if new_path:
                    return new_path
        return None

    def __str__(self):
        return '{}({})'.format(self.__class__.__name__, dict(self._graph))

I’ll leave it as an “exercise for the reader” to create a find_shortest_path and other methods.

Let’s see this in action though…

>>> connections = [('A', 'B'), ('B', 'C'), ('B', 'D'),
                   ('C', 'D'), ('E', 'F'), ('F', 'C')]
>>> g = Graph(connections, directed=True)
>>> pretty_print = pprint.PrettyPrinter()
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'C'},
 'C': {'D'},
 'E': {'F'},
 'F': {'C'}}

>>> g = Graph(connections)  # undirected
>>> pretty_print = pprint.PrettyPrinter()
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'A', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'B'},
 'E': {'F'},
 'F': {'E', 'C'}}

>>> g.add('E', 'D')
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'A', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'}}

>>> g.remove('A')
>>> pretty_print.pprint(g._graph)
{'B': {'D', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'}}

>>> g.add('G', 'B')
>>> pretty_print.pprint(g._graph)
{'B': {'D', 'G', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'},
 'G': {'B'}}

>>> g.find_path('G', 'E')
['G', 'B', 'D', 'C', 'F', 'E']

回答 1

NetworkX是一个很棒的Python图形库。您将很难找到尚未需要的东西。

而且它是开源的,因此您可以了解他们如何实现算法。您还可以添加其他算法。

https://github.com/networkx/networkx/tree/master/networkx/algorithms

NetworkX is an awesome Python graph library. You’ll be hard pressed to find something you need that it doesn’t already do.

And it’s open source so you can see how they implemented their algorithms. You can also add additional algorithms.

https://github.com/networkx/networkx/tree/master/networkx/algorithms


回答 2

首先,经典列表矩阵表示形式的选择取决于目的(取决于您要如何使用表示形式)。众所周知的问题和算法与选择有关。对抽象表示类型的选择决定了应如何实现它。

其次,问题是顶点和边缘是否应该仅根据存在性来表达,或者它们是否携带一些额外的信息。

从Python内置数据类型的角度来看,其他任何地方包含的任何值都表示为对目标对象的(隐藏)引用。如果它是变量(即命名引用),则名称和引用始终存储在(内部)字典中。如果你不需要名字,则引用可以存储在自己的容器-在这里大概Python列表会一直被用于列表的抽象。

Python列表实现为动态引用数组,Python元组实现为具有恒定内容的静态引用数组(不能更改引用的值)。因此,它们可以很容易地被索引。这样,该列表也可以用于矩阵的实现。

表示矩阵的另一种方法是由标准模块实现的数组array-相对于存储的类型(均值)更受限制。元素直接存储值。(该列表将存储对值对象的引用)。这样,它可以提高内存效率,并且对值的访问也更快。

有时,您可能会发现有用的甚至更受限制的表示形式,例如bytearray

First, the choice of classical list vs. matrix representations depends on the purpose (on what do you want to do with the representation). The well-known problems and algorithms are related to the choice. The choice of the abstract representation kind of dictates how it should be implemented.

Second, the question is whether the vertices and edges should be expressed only in terms of existence, or whether they carry some extra information.

From Python built-in data types point-of-view, any value contained elsewhere is expressed as a (hidden) reference to the target object. If it is a variable (i.e. named reference), then the name and the reference is always stored in (an internal) dictionary. If you do not need names, then the reference can be stored in your own container — here probably Python list will always be used for the list as abstraction.

Python list is implemented as a dynamic array of references, Python tuple is implemented as static array of references with constant content (the value of references cannot be changed). Because of that they can be easily indexed. This way, the list can be used also for implementation of matrices.

Another way to represent matrices are the arrays implemented by the standard module array — more constrained with respect to the stored type, homogeneous value. The elements store the value directly. (The list stores the references to the value objects instead). This way, it is more memory efficient and also the access to the value is faster.

Sometimes, you may find useful even more restricted representation like bytearray.


回答 3

有两个出色的图形库 NetworkXigraph。您可以在GitHub上找到这两个库源代码。您始终可以看到函数的编写方式。但是我更喜欢NetworkX,因为它易于理解。
查看其代码以了解其功能。您将获得多个想法,然后可以选择如何使用数据结构制作图形。

There are two excellent graph libraries NetworkX and igraph. You can find both library source codes on GitHub. You can always see how the functions are written. But I prefer NetworkX because its easy to understand.
See their codes to know how they make the functions. You will get multiple ideas and then can choose how you want to make a graph using data structures.


如何在广度优先搜索中跟踪路径?

问题:如何在广度优先搜索中跟踪路径?

如何跟踪广度优先搜索的路径,如以下示例所示:

如果搜索key 11,则返回连接1到11 的最短列表。

[1, 4, 7, 11]

How do you trace the path of a Breadth-First Search, such that in the following example:

If searching for key 11, return the shortest list connecting 1 to 11.

[1, 4, 7, 11]

回答 0

您应该先查看http://en.wikipedia.org/wiki/Breadth-first_search


下面是一个快速实现,其中我使用列表列表表示路径队列。

# graph is in adjacent list representation
graph = {
        '1': ['2', '3', '4'],
        '2': ['5', '6'],
        '5': ['9', '10'],
        '4': ['7', '8'],
        '7': ['11', '12']
        }

def bfs(graph, start, end):
    # maintain a queue of paths
    queue = []
    # push the first path into the queue
    queue.append([start])
    while queue:
        # get the first path from the queue
        path = queue.pop(0)
        # get the last node from the path
        node = path[-1]
        # path found
        if node == end:
            return path
        # enumerate all adjacent nodes, construct a new path and push it into the queue
        for adjacent in graph.get(node, []):
            new_path = list(path)
            new_path.append(adjacent)
            queue.append(new_path)

print bfs(graph, '1', '11')

另一种方法是维护从每个节点到其父节点的映射,并在检查相邻节点时记录其父节点。搜索完成后,只需根据父映射进行回溯即可。

graph = {
        '1': ['2', '3', '4'],
        '2': ['5', '6'],
        '5': ['9', '10'],
        '4': ['7', '8'],
        '7': ['11', '12']
        }

def backtrace(parent, start, end):
    path = [end]
    while path[-1] != start:
        path.append(parent[path[-1]])
    path.reverse()
    return path


def bfs(graph, start, end):
    parent = {}
    queue = []
    queue.append(start)
    while queue:
        node = queue.pop(0)
        if node == end:
            return backtrace(parent, start, end)
        for adjacent in graph.get(node, []):
            if node not in queue :
                parent[adjacent] = node # <<<<< record its parent 
                queue.append(adjacent)

print bfs(graph, '1', '11')

上面的代码基于没有循环的假设。

You should have look at http://en.wikipedia.org/wiki/Breadth-first_search first.


Below is a quick implementation, in which I used a list of list to represent the queue of paths.

# graph is in adjacent list representation
graph = {
        '1': ['2', '3', '4'],
        '2': ['5', '6'],
        '5': ['9', '10'],
        '4': ['7', '8'],
        '7': ['11', '12']
        }

def bfs(graph, start, end):
    # maintain a queue of paths
    queue = []
    # push the first path into the queue
    queue.append([start])
    while queue:
        # get the first path from the queue
        path = queue.pop(0)
        # get the last node from the path
        node = path[-1]
        # path found
        if node == end:
            return path
        # enumerate all adjacent nodes, construct a new path and push it into the queue
        for adjacent in graph.get(node, []):
            new_path = list(path)
            new_path.append(adjacent)
            queue.append(new_path)

print bfs(graph, '1', '11')

Another approach would be maintaining a mapping from each node to its parent, and when inspecting the adjacent node, record its parent. When the search is done, simply backtrace according the parent mapping.

graph = {
        '1': ['2', '3', '4'],
        '2': ['5', '6'],
        '5': ['9', '10'],
        '4': ['7', '8'],
        '7': ['11', '12']
        }

def backtrace(parent, start, end):
    path = [end]
    while path[-1] != start:
        path.append(parent[path[-1]])
    path.reverse()
    return path


def bfs(graph, start, end):
    parent = {}
    queue = []
    queue.append(start)
    while queue:
        node = queue.pop(0)
        if node == end:
            return backtrace(parent, start, end)
        for adjacent in graph.get(node, []):
            if node not in queue :
                parent[adjacent] = node # <<<<< record its parent 
                queue.append(adjacent)

print bfs(graph, '1', '11')

The above codes are based on the assumption that there’s no cycles.


回答 1

我非常喜欢qiao的第一个答案!这里唯一缺少的是将顶点标记为已访问。

为什么我们需要这样做?
让我们想象一下,从节点11连接了另一个节点号13。现在我们的目标是找到节点13。
经过一点点运行,队列将如下所示:

[[1, 2, 6], [1, 3, 10], [1, 4, 7], [1, 4, 8], [1, 2, 5, 9], [1, 2, 5, 10]]

请注意,最后有两个路径的节点编号为10。
这意味着从节点号10开始的路径将被检查两次。在这种情况下,它看起来并不那么糟糕,因为10号节点没有任何子节点。但是,这可能真的很糟糕(即使在这里我们也会无故检查两次该节点。)
13号节点不在其中这些路径,因此程序在到达最后一个节点号为10的第二条路径之前不会返回。我们将对其进行重新检查。

我们所缺少的只是一个标记访问的节点而不要再次检查它们的集合。
这是修改后的qiao的代码:

graph = {
    1: [2, 3, 4],
    2: [5, 6],
    3: [10],
    4: [7, 8],
    5: [9, 10],
    7: [11, 12],
    11: [13]
}


def bfs(graph_to_search, start, end):
    queue = [[start]]
    visited = set()

    while queue:
        # Gets the first path in the queue
        path = queue.pop(0)

        # Gets the last node in the path
        vertex = path[-1]

        # Checks if we got to the end
        if vertex == end:
            return path
        # We check if the current node is already in the visited nodes set in order not to recheck it
        elif vertex not in visited:
            # enumerate all adjacent nodes, construct a new path and push it into the queue
            for current_neighbour in graph_to_search.get(vertex, []):
                new_path = list(path)
                new_path.append(current_neighbour)
                queue.append(new_path)

            # Mark the vertex as visited
            visited.add(vertex)


print bfs(graph, 1, 13)

该程序的输出将是:

[1, 4, 7, 11, 13]

没有轻松的检查。

I liked qiao’s first answer very much! The only thing missing here is to mark the vertexes as visited.

Why we need to do it?
Lets imagine that there is another node number 13 connected from node 11. Now our goal is to find node 13.
After a little bit of a run the queue will look like this:

[[1, 2, 6], [1, 3, 10], [1, 4, 7], [1, 4, 8], [1, 2, 5, 9], [1, 2, 5, 10]]

Note that there are TWO paths with node number 10 at the end.
Which means that the paths from node number 10 will be checked twice. In this case it doesn’t look so bad because node number 10 doesn’t have any children.. But it could be really bad (even here we will check that node twice for no reason..)
Node number 13 isn’t in those paths so the program won’t return before reaching to the second path with node number 10 at the end..And we will recheck it..

All we are missing is a set to mark the visited nodes and not to check them again..
This is qiao’s code after the modification:

graph = {
    1: [2, 3, 4],
    2: [5, 6],
    3: [10],
    4: [7, 8],
    5: [9, 10],
    7: [11, 12],
    11: [13]
}


def bfs(graph_to_search, start, end):
    queue = [[start]]
    visited = set()

    while queue:
        # Gets the first path in the queue
        path = queue.pop(0)

        # Gets the last node in the path
        vertex = path[-1]

        # Checks if we got to the end
        if vertex == end:
            return path
        # We check if the current node is already in the visited nodes set in order not to recheck it
        elif vertex not in visited:
            # enumerate all adjacent nodes, construct a new path and push it into the queue
            for current_neighbour in graph_to_search.get(vertex, []):
                new_path = list(path)
                new_path.append(current_neighbour)
                queue.append(new_path)

            # Mark the vertex as visited
            visited.add(vertex)


print bfs(graph, 1, 13)

The output of the program will be:

[1, 4, 7, 11, 13]

Without the unneccecery rechecks..


回答 2

非常简单的代码。每次发现节点时,您都​​会追加路径。

graph = {
         'A': set(['B', 'C']),
         'B': set(['A', 'D', 'E']),
         'C': set(['A', 'F']),
         'D': set(['B']),
         'E': set(['B', 'F']),
         'F': set(['C', 'E'])
         }
def retunShortestPath(graph, start, end):

    queue = [(start,[start])]
    visited = set()

    while queue:
        vertex, path = queue.pop(0)
        visited.add(vertex)
        for node in graph[vertex]:
            if node == end:
                return path + [end]
            else:
                if node not in visited:
                    visited.add(node)
                    queue.append((node, path + [node]))

Very easy code. You keep appending the path each time you discover a node.

graph = {
         'A': set(['B', 'C']),
         'B': set(['A', 'D', 'E']),
         'C': set(['A', 'F']),
         'D': set(['B']),
         'E': set(['B', 'F']),
         'F': set(['C', 'E'])
         }
def retunShortestPath(graph, start, end):

    queue = [(start,[start])]
    visited = set()

    while queue:
        vertex, path = queue.pop(0)
        visited.add(vertex)
        for node in graph[vertex]:
            if node == end:
                return path + [end]
            else:
                if node not in visited:
                    visited.add(node)
                    queue.append((node, path + [node]))

回答 3

我以为我会尝试将此代码编写起来很有趣:

graph = {
        '1': ['2', '3', '4'],
        '2': ['5', '6'],
        '5': ['9', '10'],
        '4': ['7', '8'],
        '7': ['11', '12']
        }

def bfs(graph, forefront, end):
    # assumes no cycles

    next_forefront = [(node, path + ',' + node) for i, path in forefront if i in graph for node in graph[i]]

    for node,path in next_forefront:
        if node==end:
            return path
    else:
        return bfs(graph,next_forefront,end)

print bfs(graph,[('1','1')],'11')

# >>>
# 1, 4, 7, 11

如果需要循环,可以添加以下内容:

for i, j in for_front: # allow cycles, add this code
    if i in graph:
        del graph[i]

I thought I’d try code this up for fun:

graph = {
        '1': ['2', '3', '4'],
        '2': ['5', '6'],
        '5': ['9', '10'],
        '4': ['7', '8'],
        '7': ['11', '12']
        }

def bfs(graph, forefront, end):
    # assumes no cycles

    next_forefront = [(node, path + ',' + node) for i, path in forefront if i in graph for node in graph[i]]

    for node,path in next_forefront:
        if node==end:
            return path
    else:
        return bfs(graph,next_forefront,end)

print bfs(graph,[('1','1')],'11')

# >>>
# 1, 4, 7, 11

If you want cycles you could add this:

for i, j in for_front: # allow cycles, add this code
    if i in graph:
        del graph[i]

回答 4

我既喜欢@乔的第一个答案,又喜欢@Or的加法。为了减少处理量,我想补充一下Or的答案。

在@Or的答案中,访问节点的跟踪很棒。我们还可以允许程序比当前状态早退出。在for循环的某个点上,current_neighbour必须是end,一旦发生,就会找到最短路径,程序可以返回。

我将修改方法如下,请密切注意for循环

graph = {
1: [2, 3, 4],
2: [5, 6],
3: [10],
4: [7, 8],
5: [9, 10],
7: [11, 12],
11: [13]
}


    def bfs(graph_to_search, start, end):
        queue = [[start]]
        visited = set()

    while queue:
        # Gets the first path in the queue
        path = queue.pop(0)

        # Gets the last node in the path
        vertex = path[-1]

        # Checks if we got to the end
        if vertex == end:
            return path
        # We check if the current node is already in the visited nodes set in order not to recheck it
        elif vertex not in visited:
            # enumerate all adjacent nodes, construct a new path and push it into the queue
            for current_neighbour in graph_to_search.get(vertex, []):
                new_path = list(path)
                new_path.append(current_neighbour)
                queue.append(new_path)

                #No need to visit other neighbour. Return at once
                if current_neighbour == end
                    return new_path;

            # Mark the vertex as visited
            visited.add(vertex)


print bfs(graph, 1, 13)

输出和其他所有内容都将相同。但是,该代码将花费更少的时间来处理。这在较大的图上特别有用。我希望这对以后的人有所帮助。

I like both @Qiao first answer and @Or’s addition. For a sake of a little less processing I would like to add to Or’s answer.

In @Or’s answer keeping track of visited node is great. We can also allow the program to exit sooner that it currently is. At some point in the for loop the current_neighbour will have to be the end, and once that happens the shortest path is found and program can return.

I would modify the the method as follow, pay close attention to the for loop

graph = {
1: [2, 3, 4],
2: [5, 6],
3: [10],
4: [7, 8],
5: [9, 10],
7: [11, 12],
11: [13]
}


    def bfs(graph_to_search, start, end):
        queue = [[start]]
        visited = set()

    while queue:
        # Gets the first path in the queue
        path = queue.pop(0)

        # Gets the last node in the path
        vertex = path[-1]

        # Checks if we got to the end
        if vertex == end:
            return path
        # We check if the current node is already in the visited nodes set in order not to recheck it
        elif vertex not in visited:
            # enumerate all adjacent nodes, construct a new path and push it into the queue
            for current_neighbour in graph_to_search.get(vertex, []):
                new_path = list(path)
                new_path.append(current_neighbour)
                queue.append(new_path)

                #No need to visit other neighbour. Return at once
                if current_neighbour == end
                    return new_path;

            # Mark the vertex as visited
            visited.add(vertex)


print bfs(graph, 1, 13)

The output and everything else will be the same. However, the code will take less time to process. This is especially useful on larger graphs. I hope this helps someone in the future.


如何在python中使用networkx绘制有向图?

问题:如何在python中使用networkx绘制有向图?

我有一些来自脚本的节点,希望将其映射到图上。在下面,我想使用“箭头”从A到D,并可能将边缘也涂成红色(红色或其他颜色)。

基本上,这就像所有其他节点都存在时从A到D的路径一样。您可以想象每个节点都是城市,并且从A到D的行驶需要方向(带有箭头)。

下面的代码构建图表

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

nx.draw(G, cmap = plt.get_cmap('jet'), node_color = values)
plt.show()

但我想要类似图片中所示的内容。

第一张图片的箭头和红色边缘在第二张图片上。

I have some nodes coming from a script that I want to map on to a graph. In the below, I want to use Arrow to go from A to D and probably have the edge colored too in (red or something).

This is basically, like a path from A to D when all other nodes are present. you can imagine each nodes as cities and traveling from A to D requires directions (with arrow heads).

This code below builds the graph

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

nx.draw(G, cmap = plt.get_cmap('jet'), node_color = values)
plt.show()

but I want something like shown in the image.

Arrow heads of the first image and the edges in red color onto the second image.


回答 0

完全充实了带有红色边缘的箭头示例:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

# Specify the edges you want here
red_edges = [('A', 'C'), ('E', 'C')]
edge_colours = ['black' if not edge in red_edges else 'red'
                for edge in G.edges()]
black_edges = [edge for edge in G.edges() if edge not in red_edges]

# Need to create a layout when doing
# separate calls to draw nodes and edges
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), 
                       node_color = values, node_size = 500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edgelist=red_edges, edge_color='r', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()

Fully fleshed out example with arrows for only the red edges:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from(
    [('A', 'B'), ('A', 'C'), ('D', 'B'), ('E', 'C'), ('E', 'F'),
     ('B', 'H'), ('B', 'G'), ('B', 'F'), ('C', 'G')])

val_map = {'A': 1.0,
           'D': 0.5714285714285714,
           'H': 0.0}

values = [val_map.get(node, 0.25) for node in G.nodes()]

# Specify the edges you want here
red_edges = [('A', 'C'), ('E', 'C')]
edge_colours = ['black' if not edge in red_edges else 'red'
                for edge in G.edges()]
black_edges = [edge for edge in G.edges() if edge not in red_edges]

# Need to create a layout when doing
# separate calls to draw nodes and edges
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, cmap=plt.get_cmap('jet'), 
                       node_color = values, node_size = 500)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edgelist=red_edges, edge_color='r', arrows=True)
nx.draw_networkx_edges(G, pos, edgelist=black_edges, arrows=False)
plt.show()


回答 1

我仅出于完整性考虑。我从marius和mdml学到了很多东西。这是边缘权重。对不起,箭头。看来我并不是唯一无法解决的人。我无法使用ipython笔记本渲染此图像,我不得不直接从python着手,这是尽快获得边缘权重的问题。

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pylab

G = nx.DiGraph()

G.add_edges_from([('A', 'B'),('C','D'),('G','D')], weight=1)
G.add_edges_from([('D','A'),('D','E'),('B','D'),('D','E')], weight=2)
G.add_edges_from([('B','C'),('E','F')], weight=3)
G.add_edges_from([('C','F')], weight=4)


val_map = {'A': 1.0,
                   'D': 0.5714285714285714,
                              'H': 0.0}

values = [val_map.get(node, 0.45) for node in G.nodes()]
edge_labels=dict([((u,v,),d['weight'])
                 for u,v,d in G.edges(data=True)])
red_edges = [('C','D'),('D','A')]
edge_colors = ['black' if not edge in red_edges else 'red' for edge in G.edges()]

pos=nx.spring_layout(G)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
nx.draw(G,pos, node_color = values, node_size=1500,edge_color=edge_colors,edge_cmap=plt.cm.Reds)
pylab.show()

I only put this in for completeness. I’ve learned plenty from marius and mdml. Here are the edge weights. Sorry about the arrows. Looks like I’m not the only one saying it can’t be helped. I couldn’t render this with ipython notebook I had to go straight from python which was the problem with getting my edge weights in sooner.

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pylab

G = nx.DiGraph()

G.add_edges_from([('A', 'B'),('C','D'),('G','D')], weight=1)
G.add_edges_from([('D','A'),('D','E'),('B','D'),('D','E')], weight=2)
G.add_edges_from([('B','C'),('E','F')], weight=3)
G.add_edges_from([('C','F')], weight=4)


val_map = {'A': 1.0,
                   'D': 0.5714285714285714,
                              'H': 0.0}

values = [val_map.get(node, 0.45) for node in G.nodes()]
edge_labels=dict([((u,v,),d['weight'])
                 for u,v,d in G.edges(data=True)])
red_edges = [('C','D'),('D','A')]
edge_colors = ['black' if not edge in red_edges else 'red' for edge in G.edges()]

pos=nx.spring_layout(G)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
nx.draw(G,pos, node_color = values, node_size=1500,edge_color=edge_colors,edge_cmap=plt.cm.Reds)
pylab.show()


回答 2

您可能要使用常规的nx.draw来代替:

nx.draw_networkx(G[, pos, arrows, with_labels])

例如:

nx.draw_networkx(G, arrows=True, **options)

您可以通过初始化**变量来添加选项,如下所示:

options = {
    'node_color': 'blue',
    'node_size': 100,
    'width': 3,
    'arrowstyle': '-|>',
    'arrowsize': 12,
}

也有一些功能支持directed=True parameter 在这种情况下,此状态是默认状态:

G = nx.DiGraph(directed=True)

这里可以找到networkx参考。

Instead of regular nx.draw you may want to use:

nx.draw_networkx(G[, pos, arrows, with_labels])

For example:

nx.draw_networkx(G, arrows=True, **options)

You can add options by initialising that ** variable like this:

options = {
    'node_color': 'blue',
    'node_size': 100,
    'width': 3,
    'arrowstyle': '-|>',
    'arrowsize': 12,
}

Also some functions support the directed=True parameter In this case this state is the default one:

G = nx.DiGraph(directed=True)

The networkx reference is found here.


回答 3

您需要使用有向图而不是图,即

G = nx.DiGraph()

然后,创建要使用的边缘颜色的列表,并将其传递给 nx.draw(如@Marius所示)。

放在一起,我得到下面的图像。仍然不是您显示的其他图片(我不知道您的边缘权重来自何处),而是更接近!如果您想更好地控制输出图形的外观(例如,获得箭头形状的箭头),请使用Graphviz来检查NetworkX

You need to use a directed graph instead of a graph, i.e.

G = nx.DiGraph()

Then, create a list of the edge colors you want to use and pass those to nx.draw (as shown by @Marius).

Putting this all together, I get the image below. Still not quite the other picture you show (I don’t know where your edge weights are coming from), but much closer! If you want more control of how your output graph looks (e.g. get arrowheads that look like arrows), I’d check out NetworkX with Graphviz.


回答 4

import networkx as nx
import matplotlib.pyplot as plt

g = nx.DiGraph()
g.add_nodes_from([1,2,3,4,5])
g.add_edge(1,2)
g.add_edge(4,2)
g.add_edge(3,5)
g.add_edge(2,3)
g.add_edge(5,4)

nx.draw(g,with_labels=True)
plt.draw()
plt.show()

这只是简单的方法,即使用networkx使用python 3.x绘制有向图。只是简单的表示形式,可以进行修改和着色等。请参见此处生成的图形。

注意:这只是一个简单的表示。加权边可以像

g.add_edges_from([(1,2),(2,5)], weight=2)

因此再次绘制。

import networkx as nx
import matplotlib.pyplot as plt

g = nx.DiGraph()
g.add_nodes_from([1,2,3,4,5])
g.add_edge(1,2)
g.add_edge(4,2)
g.add_edge(3,5)
g.add_edge(2,3)
g.add_edge(5,4)

nx.draw(g,with_labels=True)
plt.draw()
plt.show()

This is just simple how to draw directed graph using python 3.x using networkx. just simple representation and can be modified and colored etc. See the generated graph here.

Note: It’s just a simple representation. Weighted Edges could be added like

g.add_edges_from([(1,2),(2,5)], weight=2)

and hence plotted again.


回答 5

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node("A")
G.add_node("B")
G.add_node("C")
G.add_node("D")
G.add_node("E")
G.add_node("F")
G.add_node("G")
G.add_edge("A","B")
G.add_edge("B","C")
G.add_edge("C","E")
G.add_edge("C","F")
G.add_edge("D","E")
G.add_edge("F","G")

print(G.nodes())
print(G.edges())

pos = nx.spring_layout(G)

nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edge_color='r', arrows = True)

plt.show()
import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node("A")
G.add_node("B")
G.add_node("C")
G.add_node("D")
G.add_node("E")
G.add_node("F")
G.add_node("G")
G.add_edge("A","B")
G.add_edge("B","C")
G.add_edge("C","E")
G.add_edge("C","F")
G.add_edge("D","E")
G.add_edge("F","G")

print(G.nodes())
print(G.edges())

pos = nx.spring_layout(G)

nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edge_color='r', arrows = True)

plt.show()

使用Matplotlib在Python中绘制时间

问题:使用Matplotlib在Python中绘制时间

我有一个格式为(HH:MM:SS.mmmmmm)的时间戳数组和另一个浮点数数组,每个浮点数对应于timestamp数组中的一个值。

我可以使用Matplotlib在x轴上绘制时间,在y轴上绘制数字吗?

我试图这样做,但是不知何故它只接受浮点数数组。如何获取时间图?我必须以任何方式修改格式吗?

I have an array of timestamps in the format (HH:MM:SS.mmmmmm) and another array of floating point numbers, each corresponding to a value in the timestamp array.

Can I plot time on the x axis and the numbers on the y-axis using Matplotlib?

I was trying to, but somehow it was only accepting arrays of floats. How can I get it to plot the time? Do I have to modify the format in any way?


回答 0

您必须首先将时间戳转换为Python datetime对象(使用datetime.strptime)。然后使用date2num将日期转换为matplotlib格式。

使用plot_date以下方式绘制日期和值:

dates = matplotlib.dates.date2num(list_of_datetimes)
matplotlib.pyplot.plot_date(dates, values)

You must first convert your timestamps to Python datetime objects (use datetime.strptime). Then use date2num to convert the dates to matplotlib format.

Plot the dates and values using plot_date:

dates = matplotlib.dates.date2num(list_of_datetimes)
matplotlib.pyplot.plot_date(dates, values)

回答 1

您还可以使用pyplot.plot绘制时间戳,值对(从它们的字符串表示形式解析它们之后)。(使用matplotlib 1.2.0和1.3.1版进行了测试)

例:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

结果图像:


这与散点图相同:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

产生类似于此的图像:

You can also plot the timestamp, value pairs using pyplot.plot (after parsing them from their string representation). (Tested with matplotlib versions 1.2.0 and 1.3.1.)

Example:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Resulting image:


Here’s the same as a scatter plot:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Produces an image similar to this:


回答 2

7年后,这段代码对我有所帮助。但是,我的时间仍然没有正确显示。

使用Matplotlib 2.0.0,我不得不从Paul H 编辑matplotlib中编辑x轴刻度标签的日期格式中添加以下代码。

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)

我将格式更改为(%H:%M),并且时间显示正确。

非常感谢社区。

7 years later and this code has helped me. However, my times still were not showing up correctly.

Using Matplotlib 2.0.0 and I had to add the following bit of code from Editing the date formatting of x-axis tick labels in matplotlib by Paul H.

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)

I changed the format to (%H:%M) and the time displayed correctly.

All thanks to the community.


回答 3

我在使用matplotlib版本2.0.2时遇到了麻烦。从上面运行示例,我得到了一组居中的气泡集合。

我通过添加另一行“修复”了该问题:

plt.plot([],[])

整个代码段变为:

import datetime
import random
import matplotlib.pyplot as plt
import matplotlib.dates as mdates


# make up some data
x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot([],[])
plt.scatter(x,y)

# beautify the x-labels
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%H:%M')
plt.gca().xaxis.set_major_formatter(myFmt)

plt.show()
plt.close()

这将生成图像,其中气泡按需分布。

I had trouble with this using matplotlib version: 2.0.2. Running the example from above I got a centered stacked set of bubbles.

I “fixed” the problem by adding another line:

plt.plot([],[])

The entire code snippet becomes:

import datetime
import random
import matplotlib.pyplot as plt
import matplotlib.dates as mdates


# make up some data
x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot([],[])
plt.scatter(x,y)

# beautify the x-labels
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%H:%M')
plt.gca().xaxis.set_major_formatter(myFmt)

plt.show()
plt.close()

This produces an image with the bubbles distributed as desired.


在matplotlib中设置颜色栏范围

问题:在matplotlib中设置颜色栏范围

我有以下代码:

import matplotlib.pyplot as plt

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

plt.clf()
plt.pcolor(X, Y, v, cmap=cm)
plt.loglog()
plt.xlabel('X Axis')
plt.ylabel('Y Axis')

plt.colorbar()
plt.show()

因此,这将使用指定的颜色图在X轴和Y轴上生成值“ v”的图形。X和Y轴是完美的,但是颜色图在v的最小值和最大值之间分布。我想强制颜色图的范围在0到1之间。

我想到使用:

plt.axis(...)

设置轴的范围,但这仅接受X和Y的最小值和最大值的参数,而不使用颜色图。

编辑:

为了清楚起见,假设我有一个图的值的范围为(0 … 0.3),而另一个图的值为(0.2 … 0.8)。

在两个图中,我都希望颜色条的范围为(0 … 1)。在两个图中,我希望使用上述整个cdict范围时该颜色范围是相同的(因此,两个图中的0.25将是相同颜色)。在第一个图形中,介于0.3到1.0之间的所有颜色将不会显示在图形中,但是会在侧面的颜色栏键中显示。另一方面,所有介于0和0.2之间以及介于0.8和1之间的颜色都不会出现在图表中,而是会出现在侧面的颜色栏中。

I have the following code:

import matplotlib.pyplot as plt

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

plt.clf()
plt.pcolor(X, Y, v, cmap=cm)
plt.loglog()
plt.xlabel('X Axis')
plt.ylabel('Y Axis')

plt.colorbar()
plt.show()

So this produces a graph of the values ‘v’ on the axes X vs Y, using the specified colormap. The X and Y axes are perfect, but the colormap spreads between the min and max of v. I would like to force the colormap to range between 0 and 1.

I thought of using:

plt.axis(...)

To set the ranges of the axes, but this only takes arguments for the min and max of X and Y, not the colormap.

Edit:

For clarity, let’s say I have one graph whose values range (0 … 0.3), and another graph whose values (0.2 … 0.8).

In both graphs, I will want the range of the colorbar to be (0 … 1). In both graphs, I want this range of colour to be identical using the full range of cdict above (so 0.25 in both graphs will be the same colour). In the first graph, all colours between 0.3 and 1.0 won’t feature in the graph, but will in the colourbar key at the side. In the other, all colours between 0 and 0.2, and between 0.8 and 1 will not feature in the graph, but will in the colourbar at the side.


回答 0

使用vminvmax强制使用颜色范围。这是一个例子:

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )

def do_plot(n, f, title):
    #plt.clf()
    plt.subplot(1, 3, n)
    plt.pcolor(X, Y, f(data), cmap=cm, vmin=-4, vmax=4)
    plt.title(title)
    plt.colorbar()

plt.figure()
do_plot(1, lambda x:x, "all")
do_plot(2, lambda x:np.clip(x, -4, 0), "<0")
do_plot(3, lambda x:np.clip(x, 0, 4), ">0")
plt.show()

Using vmin and vmax forces the range for the colors. Here’s an example:

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )

def do_plot(n, f, title):
    #plt.clf()
    plt.subplot(1, 3, n)
    plt.pcolor(X, Y, f(data), cmap=cm, vmin=-4, vmax=4)
    plt.title(title)
    plt.colorbar()

plt.figure()
do_plot(1, lambda x:x, "all")
do_plot(2, lambda x:np.clip(x, -4, 0), "<0")
do_plot(3, lambda x:np.clip(x, 0, 4), ">0")
plt.show()

回答 1

使用CLIM函数(相当于MATLAB中的CAXIS函数):

plt.pcolor(X, Y, v, cmap=cm)
plt.clim(-4,4)  # identical to caxis([-4,4]) in MATLAB
plt.show()

Use the CLIM function (equivalent to CAXIS function in MATLAB):

plt.pcolor(X, Y, v, cmap=cm)
plt.clim(-4,4)  # identical to caxis([-4,4]) in MATLAB
plt.show()

回答 2

不知道这是否是最优雅的解决方案(这就是我使用的解决方案),但是您可以将数据缩放到0到1之间的范围,然后修改颜色栏:

import matplotlib as mpl
...
ax, _ = mpl.colorbar.make_axes(plt.gca(), shrink=0.5)
cbar = mpl.colorbar.ColorbarBase(ax, cmap=cm,
                       norm=mpl.colors.Normalize(vmin=-0.5, vmax=1.5))
cbar.set_clim(-2.0, 2.0)

使用两个不同的限制,您可以控制颜色栏的范围和图例。在此示例中,栏中仅显示-0.5到1.5之间的范围,而色图则覆盖-2到2(因此这可能是您的数据范围,您在缩放之前记录了该范围)。

因此,您不必缩放颜色图,而是可以缩放数据并使颜色条适合该值。

Not sure if this is the most elegant solution (this is what I used), but you could scale your data to the range between 0 to 1 and then modify the colorbar:

import matplotlib as mpl
...
ax, _ = mpl.colorbar.make_axes(plt.gca(), shrink=0.5)
cbar = mpl.colorbar.ColorbarBase(ax, cmap=cm,
                       norm=mpl.colors.Normalize(vmin=-0.5, vmax=1.5))
cbar.set_clim(-2.0, 2.0)

With the two different limits you can control the range and legend of the colorbar. In this example only the range between -0.5 to 1.5 is show in the bar, while the colormap covers -2 to 2 (so this could be your data range, which you record before the scaling).

So instead of scaling the colormap you scale your data and fit the colorbar to that.


回答 3

使用图形环境和.set_clim()

如果您有多个图,可能会更容易,更安全地进行此选择:

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )
data1 = np.clip(data,0,6)
data2 = np.clip(data,-6,0)
vmin = np.min(np.array([data,data1,data2]))
vmax = np.max(np.array([data,data1,data2]))

fig = plt.figure()
ax = fig.add_subplot(131)
mesh = ax.pcolormesh(data, cmap = cm)
mesh.set_clim(vmin,vmax)
ax1 = fig.add_subplot(132)
mesh1 = ax1.pcolormesh(data1, cmap = cm)
mesh1.set_clim(vmin,vmax)
ax2 = fig.add_subplot(133)
mesh2 = ax2.pcolormesh(data2, cmap = cm)
mesh2.set_clim(vmin,vmax)
# Visualizing colorbar part -start
fig.colorbar(mesh,ax=ax)
fig.colorbar(mesh1,ax=ax1)
fig.colorbar(mesh2,ax=ax2)
fig.tight_layout()
# Visualizing colorbar part -end

plt.show()

单个彩条

最好的选择是对整个图使用单个颜色条。有多种方法可以完成此操作,教程对于了解最佳选择非常有用。我更喜欢这种解决方案,您只需复制和粘贴即可,而不是之前的可视化颜色栏代码。

fig.subplots_adjust(bottom=0.1, top=0.9, left=0.1, right=0.8,
                    wspace=0.4, hspace=0.1)
cb_ax = fig.add_axes([0.83, 0.1, 0.02, 0.8])
cbar = fig.colorbar(mesh, cax=cb_ax)

聚苯乙烯

我建议使用pcolormesh代替,pcolor因为它速度更快(此处有更多信息)。

Using figure environment and .set_clim()

Could be easier and safer this alternative if you have multiple plots:

import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )
data1 = np.clip(data,0,6)
data2 = np.clip(data,-6,0)
vmin = np.min(np.array([data,data1,data2]))
vmax = np.max(np.array([data,data1,data2]))

fig = plt.figure()
ax = fig.add_subplot(131)
mesh = ax.pcolormesh(data, cmap = cm)
mesh.set_clim(vmin,vmax)
ax1 = fig.add_subplot(132)
mesh1 = ax1.pcolormesh(data1, cmap = cm)
mesh1.set_clim(vmin,vmax)
ax2 = fig.add_subplot(133)
mesh2 = ax2.pcolormesh(data2, cmap = cm)
mesh2.set_clim(vmin,vmax)
# Visualizing colorbar part -start
fig.colorbar(mesh,ax=ax)
fig.colorbar(mesh1,ax=ax1)
fig.colorbar(mesh2,ax=ax2)
fig.tight_layout()
# Visualizing colorbar part -end

plt.show()

A single colorbar

The best alternative is then to use a single color bar for the entire plot. There are different ways to do that, this tutorial is very useful for understanding the best option. I prefer this solution that you can simply copy and paste instead of the previous visualizing colorbar part of the code.

fig.subplots_adjust(bottom=0.1, top=0.9, left=0.1, right=0.8,
                    wspace=0.4, hspace=0.1)
cb_ax = fig.add_axes([0.83, 0.1, 0.02, 0.8])
cbar = fig.colorbar(mesh, cax=cb_ax)

P.S.

I would suggest using pcolormesh instead of pcolor because it is faster (more infos here ).


未定义DISPLAY时,使用matplotlib生成PNG

问题:未定义DISPLAY时,使用matplotlib生成PNG

我正在尝试将networkx与Python结合使用。当我运行该程序时,出现此错误。缺少什么吗?

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")


Traceback (most recent call last):
  File "graph.py", line 13, in <module>
    nx.draw(G)
  File "/usr/lib/pymodules/python2.5/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

我现在收到另一个错误:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in <module>
    nx.draw(G)
  File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

我现在收到另一个错误:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in <module>
    nx.draw(G)
  File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

I am trying to use networkx with Python. When I run this program it get this error. Is there anything missing?

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")


Traceback (most recent call last):
  File "graph.py", line 13, in <module>
    nx.draw(G)
  File "/usr/lib/pymodules/python2.5/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

I get a different error now:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in <module>
    nx.draw(G)
  File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

I get a different error now:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in <module>
    nx.draw(G)
  File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
    cf=pylab.gcf()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
    return figure()
  File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
    window = Tk.Tk()
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

回答 0

主要问题是(在您的系统上)matplotlib默认情况下选择使用x的后端。我在其中一台服务器上遇到了同样的问题。对我来说,解决方案是任何其他pylab / matplotlib / pyplot导入之前先读取的位置添加以下代码:

import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')

另一种方法是在您的.matplotlibrc中进行设置

The main problem is that (on your system) matplotlib chooses an x-using backend by default. I just had the same problem on one of my servers. The solution for me was to add the following code in a place that gets read before any other pylab/matplotlib/pyplot import:

import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')

The alternative is to set it in your .matplotlibrc


回答 1

只是对Reinout的回答的补充。

解决此类问题的永久方法是编辑.matplotlibrc文件。通过找到它

>>> import matplotlib
>>> matplotlib.matplotlib_fname() # This is the file location in Ubuntu '/etc/matplotlibrc'

然后将该文件中的后端修改为backend : Agg。这就对了。

Just as a complement of Reinout’s answer.

The permanent way to solve this kind of problem is to edit .matplotlibrc file. Find it via

>>> import matplotlib
>>> matplotlib.matplotlib_fname() # This is the file location in Ubuntu '/etc/matplotlibrc'

Then modify the backend in that file to backend : Agg. That is it.


回答 2

明确的答案是花一些时间正确准备执行环境。

你必须准备执行环境第一种方法是使用一个matplotlibrc文件,明智地由克里斯Q.建议,设置

backend : Agg

在那个文件中。您甚至可以控制matplotlib查找和查找matplotlibrc文件的方式和位置,而无需更改代码。

准备执行环境的第二种技术是使用MPLBACKEND环境变量(并通知您的用户使用它):

export MPLBACKEND="agg"
python <program_using_matplotlib.py>

这很方便,因为您甚至不必在磁盘上提供另一个文件即可完成此工作。我采用了这种方法,例如进行持续集成测试,并在没有显示器的远程计算机上运行。

在您的Python代码中将matplotlib后端硬编码为“ Agg”,就像用大铁锤将方钉砸成一个圆孔,相反,您本可以告诉matplotlib它必须是方孔。

The clean answer is to take a little bit of time correctly prepare your execution environment.

The first technique you have to prepare your execution environment is to use a matplotlibrc file, as wisely recommended by Chris Q., setting

backend : Agg

in that file. You can even control — with no code changes — how and where matplotlib looks for and finds the matplotlibrc file.

The second technique you have to prepare your execution environment is to use the MPLBACKEND environment variable (and inform your users to make use of it):

export MPLBACKEND="agg"
python <program_using_matplotlib.py>

This is handy because you don’t even have to provide another file on disk to make this work. I have employed this approach with, for example, testing in continuous integration, and running on remote machines that do not have displays.

Hard-coding your matplotlib backend to “Agg” in your Python code is like bashing a square peg into a round hole with a big hammer, when, instead, you could have just told matplotlib it needs to be a square hole.


回答 3

通过Spark使用matplotlib时出现错误。matplotlib.use('Agg')对我不起作用。最后,以下代码对我有用。这里更多

import matplotlib.pyplot as plt.
plt.switch_backend('agg')

I got the error while using matplotlib through Spark. matplotlib.use('Agg') doesn’t work for me. In the end, the following code works for me. More here

import matplotlib.pyplot as plt.
plt.switch_backend('agg')

回答 4

我将重复@Ivo Bosticky所说的话,但可以忽略。将这些行放在py文件的非常开头。

import matplotlib
matplotlib.use('Agg') 

否则会出错

* / usr / lib / pymodules / python2.7 / matplotlib / __ init__.py:923:UserWarning:此对matplotlib.use()的调用无效
因为已经选择了后端;
必须在pylab,matplotlib.pyplot,*之前调用matplotlib.use()

这将解决所有显示问题

I will just repeat what @Ivo Bosticky said which can be overlooked. Put these lines at the VERY start of the py file.

import matplotlib
matplotlib.use('Agg') 

Or one would get error

*/usr/lib/pymodules/python2.7/matplotlib/__init__.py:923: UserWarning:  This call to   matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,*

This will resolve all Display issue


回答 5

我发现此片段在X和非X环境之间切换时效果很好。

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using non-interactive Agg backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt

I found this snippet to work well when switching between X and no-X environments.

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using non-interactive Agg backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt

回答 6

登录服务器以执行代码时,请改用以下命令:

ssh -X username@servername

-X将摆脱没有显示名称并且没有$ DISPLAY环境变量错误

:)

When signing into the server to execute the code use this instead:

ssh -X username@servername

the -X will get rid of the no display name and no $DISPLAY environment variable error

:)


回答 7

您在什么系统上?看起来您的系统具有X11,但未正确设置DISPLAY环境变量。尝试执行以下命令,然后重新运行程序:

export DISPLAY=localhost:0

What system are you on? It looks like you have a system with X11, but the DISPLAY environment variable was not properly set. Try executing the following command and then rerunning your program:

export DISPLAY=localhost:0

回答 8

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

这个对我有用。

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

It works for me.


回答 9

要检查的另一件事是您当前的用户是否有权连接到X显示器。在我的情况下,不允许root执行此操作,并且matplotlib抱怨同样的错误。

user@debian:~$ xauth list         
debian/unix:10  MIT-MAGIC-COOKIE-1  ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xauth add debian/unix:10  MIT-MAGIC-COOKIE-1 ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xterm

来源:http : //www.debian-administration.org/articles/494 https://debian-administration.org/article/494/Getting_X11_forwarding_through_ssh_working_after_running_su

One other thing to check is whether your current user is authorised to connect to the X display. In my case, root was not allowed to do that and matplotlib was complaining with the same error.

user@debian:~$ xauth list         
debian/unix:10  MIT-MAGIC-COOKIE-1  ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xauth add debian/unix:10  MIT-MAGIC-COOKIE-1 ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xterm

source: http://www.debian-administration.org/articles/494 https://debian-administration.org/article/494/Getting_X11_forwarding_through_ssh_working_after_running_su


回答 10

为了确保您的代码可在Windows,Linux和OSX上移植,以及对于带有和不带有显示器的系统,我建议使用以下代码段:

import matplotlib
import os
# must be before importing matplotlib.pyplot or pylab!
if os.name == 'posix' and "DISPLAY" not in os.environ:
    matplotlib.use('Agg')

# now import other things from matplotlib
import matplotlib.pyplot as plt

信用:https : //stackoverflow.com/a/45756291/207661

To make sure your code is portable across Windows, Linux and OSX and for systems with and without displays, I would suggest following snippet:

import matplotlib
import os
# must be before importing matplotlib.pyplot or pylab!
if os.name == 'posix' and "DISPLAY" not in os.environ:
    matplotlib.use('Agg')

# now import other things from matplotlib
import matplotlib.pyplot as plt

Credit: https://stackoverflow.com/a/45756291/207661


回答 11

对于Google Cloud Machine Learning Engine:

import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages

然后打印到文件:

#PDF build and save
    def multi_page(filename, figs=None, dpi=200):
        pp = PdfPages(filename)
        if figs is None:
            figs = [mpl.pyplot.figure(n) for n in mpl.pyplot.get_fignums()]
        for fig in figs:
            fig.savefig(pp, format='pdf', bbox_inches='tight', fig_size=(10, 8))
        pp.close()

并创建PDF:

multi_page(report_name)

For Google Cloud Machine Learning Engine:

import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages

And then to print to file:

#PDF build and save
    def multi_page(filename, figs=None, dpi=200):
        pp = PdfPages(filename)
        if figs is None:
            figs = [mpl.pyplot.figure(n) for n in mpl.pyplot.get_fignums()]
        for fig in figs:
            fig.savefig(pp, format='pdf', bbox_inches='tight', fig_size=(10, 8))
        pp.close()

and to create the PDF:

multi_page(report_name)

Python图形库[关闭]

问题:Python图形库[关闭]

我正在编写一个将大量使用图形数据结构的python应用程序。没什么可怕的,但是我在想某种图形/图形算法库可以帮助我。我已经四处搜寻,但没有发现特别令我惊讶的地方。

有人有什么好的建议吗?

I’m writing a python application that will make heavy use of a graph data structure. Nothing horribly complex, but I’m thinking some sort of graph/graph-algorithms library would help me out. I’ve googled around, but I don’t find anything that particularly leaps out at me.

Anyone have any good recommendations?


回答 0

有两个绝佳的选择:

网络X

我喜欢NetworkX,但我也阅读有关igraph的好文章。我通常将NetworkX与具有1百万个节点的图一起使用而没有问题(这是大小为V + E的字典的开销的两倍)

如果要进行功能比较,请从Networkx讨论列表中查看

功能比较线程

There are two excellent choices:

NetworkX

and

igraph

I like NetworkX, but I read good things about igraph as well. I routinely use NetworkX with graphs with 1 million nodes with no problem (it’s about double the overhead of a dict of size V + E)

If you want a feature comparison, see this from the Networkx-discuss list

Feature comparison thread


回答 1

我想插入自己的图python库: graph-tool

它非常快,因为它是通过Boost Graph库的C ++实现的,并且包含许多算法和大量文档。

I would like to plug my own graph python library: graph-tool.

It is very fast, since it is implemented in C++ with the Boost Graph Library, and it contains lots of algorithms and extensive documentation.


回答 2

你看过python-graph吗?我自己没有使用过,但是项目页面看起来很有希望。

Have you looked at python-graph? I haven’t used it myself, but the project page looks promising.


回答 3

另外,您可能想看看NetworkX

Also, you might want to take a look at NetworkX


回答 4


回答 5

看一下有关在python中实现图形的页面

您也可以在sourceforge上查看pygraphlib

Take a look at this page on implementing graphs in python.

You could also take a look at pygraphlib on sourceforge.


回答 6

我的pydot最幸运。其他一些很难在像Win 7这样的不同平台上安装和配置。

http://code.google.com/p/pydot/

I’m having the most luck with pydot. Some of the others are hard to install and configure on different platforms like Win 7.

http://code.google.com/p/pydot/


回答 7

我第二次zweiterlinde建议使用python-graph。我已将其用作我正在从事的基于图的研究项目的基础。该库编写良好,稳定且具有良好的接口。作者还可以迅速答复查询和报告。

I second zweiterlinde’s suggestion to use python-graph. I’ve used it as the basis of a graph-based research project that I’m working on. The library is well written, stable, and has a good interface. The authors are also quick to respond to inquiries and reports.


您如何更改用matplotlib绘制的图形的大小?

问题:您如何更改用matplotlib绘制的图形的大小?

如何更改用matplotlib绘制的图形的大小?

How do you change the size of figure drawn with matplotlib?


回答 0

该图告诉您呼叫签名:

from matplotlib.pyplot import figure
figure(num=None, figsize=(8, 6), dpi=80, facecolor='w', edgecolor='k')

figure(figsize=(1,1)) 会创建一个一英寸一英寸的图像,该图像将是80 x 80像素,除非您还指定了不同的dpi参数。

figure tells you the call signature:

from matplotlib.pyplot import figure
figure(num=None, figsize=(8, 6), dpi=80, facecolor='w', edgecolor='k')

figure(figsize=(1,1)) would create an inch-by-inch image, which would be 80-by-80 pixels unless you also give a different dpi argument.


回答 1

如果您已经创建了图形,则可以快速执行以下操作:

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(18.5, 10.5)
fig.savefig('test2png.png', dpi=100)

要将大小更改传播到现有的GUI窗口,请添加 forward=True

fig.set_size_inches(18.5, 10.5, forward=True)

If you’ve already got the figure created you can quickly do this:

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(18.5, 10.5)
fig.savefig('test2png.png', dpi=100)

To propagate the size change to an existing gui window add forward=True

fig.set_size_inches(18.5, 10.5, forward=True)

回答 2

弃用说明:
根据官方Matplotlib指南pylab不再建议使用该模块。请考虑使用该matplotlib.pyplot模块,如该其他答案所述

以下似乎有效:

from pylab import rcParams
rcParams['figure.figsize'] = 5, 10

这使图形的宽度为5英寸,高度为10 英寸

然后,Figure类将其用作其参数之一的默认值。

Deprecation note:
As per the official Matplotlib guide, usage of the pylab module is no longer recommended. Please consider using the matplotlib.pyplot module instead, as described by this other answer.

The following seems to work:

from pylab import rcParams
rcParams['figure.figsize'] = 5, 10

This makes the figure’s width 5 inches, and its height 10 inches.

The Figure class then uses this as the default value for one of its arguments.


回答 3

使用plt.rcParams

如果您想在不使用图形环境的情况下更改大小,也可以使用此解决方法。因此,plt.plot()例如在使用时,可以设置宽度和高度的元组。

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = (20,3)

当您以内联方式绘制时(例如,使用IPython Notebook),这非常有用。正如@asamaier所注意的那样,最好不要将此语句放在import语句的同一单元格中。

转换为厘米

figsize元组接受英寸所以,如果你想将其设置成你必须2.54分他们厘米,看一下这个问题

USING plt.rcParams

There is also this workaround in case you want to change the size without using the figure environment. So in case you are using plt.plot() for example, you can set a tuple with width and height.

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = (20,3)

This is very useful when you plot inline (e.g. with IPython Notebook). As @asamaier noticed is preferable to not put this statement in the same cell of the imports statements.

Conversion to cm

The figsize tuple accepts inches so if you want to set it in centimetres you have to divide them by 2.54 have a look to this question.


回答 4

请尝试以下简单代码:

from matplotlib import pyplot as plt
plt.figure(figsize=(1,1))
x = [1,2,3]
plt.plot(x, x)
plt.show()

在绘制之前,需要设置图形尺寸。

Please try a simple code as following:

from matplotlib import pyplot as plt
plt.figure(figsize=(1,1))
x = [1,2,3]
plt.plot(x, x)
plt.show()

You need to set the figure size before you plot.


回答 5

如果您正在寻找一种方法来更改Pandas中的图形大小,可以执行例如:

df['some_column'].plot(figsize=(10, 5))

df熊猫数据框在哪里。或者,使用现有图形或轴

fig, ax = plt.subplots(figsize=(10,5))
df['some_column'].plot(ax=ax)

如果要更改默认设置,可以执行以下操作:

import matplotlib

matplotlib.rc('figure', figsize=(10, 5))

In case you’re looking for a way to change the figure size in Pandas, you could do e.g.:

df['some_column'].plot(figsize=(10, 5))

where df is a Pandas dataframe. Or, to use existing figure or axes

fig, ax = plt.subplots(figsize=(10,5))
df['some_column'].plot(ax=ax)

If you want to change the default settings, you could do the following:

import matplotlib

matplotlib.rc('figure', figsize=(10, 5))

回答 6

Google中的第一个链接'matplotlib figure size'AdjustingImageSize页面的Google缓存)。

这是上一页的测试脚本。它创建test[1-3].png同一图像的不同大小的文件:

#!/usr/bin/env python
"""
This is a small demo file that helps teach how to adjust figure sizes
for matplotlib

"""

import matplotlib
print "using MPL version:", matplotlib.__version__
matplotlib.use("WXAgg") # do this before pylab so you don'tget the default back end.

import pylab
import numpy as np

# Generate and plot some simple data:
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)

pylab.plot(x,y)
F = pylab.gcf()

# Now check everything with the defaults:
DPI = F.get_dpi()
print "DPI:", DPI
DefaultSize = F.get_size_inches()
print "Default size in Inches", DefaultSize
print "Which should result in a %i x %i Image"%(DPI*DefaultSize[0], DPI*DefaultSize[1])
# the default is 100dpi for savefig:
F.savefig("test1.png")
# this gives me a 797 x 566 pixel image, which is about 100 DPI

# Now make the image twice as big, while keeping the fonts and all the
# same size
F.set_size_inches( (DefaultSize[0]*2, DefaultSize[1]*2) )
Size = F.get_size_inches()
print "Size in Inches", Size
F.savefig("test2.png")
# this results in a 1595x1132 image

# Now make the image twice as big, making all the fonts and lines
# bigger too.

F.set_size_inches( DefaultSize )# resetthe size
Size = F.get_size_inches()
print "Size in Inches", Size
F.savefig("test3.png", dpi = (200)) # change the dpi
# this also results in a 1595x1132 image, but the fonts are larger.

输出:

using MPL version: 0.98.1
DPI: 80
Default size in Inches [ 8.  6.]
Which should result in a 640 x 480 Image
Size in Inches [ 16.  12.]
Size in Inches [ 16.  12.]

两个注意事项:

  1. 模块注释和实际输出不同。

  2. 通过此答案,可以轻松地将所有三个图像合并到一个图像文件中,以查看大小的差异。

The first link in Google for 'matplotlib figure size' is AdjustingImageSize (Google cache of the page).

Here’s a test script from the above page. It creates test[1-3].png files of different sizes of the same image:

#!/usr/bin/env python
"""
This is a small demo file that helps teach how to adjust figure sizes
for matplotlib

"""

import matplotlib
print "using MPL version:", matplotlib.__version__
matplotlib.use("WXAgg") # do this before pylab so you don'tget the default back end.

import pylab
import numpy as np

# Generate and plot some simple data:
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)

pylab.plot(x,y)
F = pylab.gcf()

# Now check everything with the defaults:
DPI = F.get_dpi()
print "DPI:", DPI
DefaultSize = F.get_size_inches()
print "Default size in Inches", DefaultSize
print "Which should result in a %i x %i Image"%(DPI*DefaultSize[0], DPI*DefaultSize[1])
# the default is 100dpi for savefig:
F.savefig("test1.png")
# this gives me a 797 x 566 pixel image, which is about 100 DPI

# Now make the image twice as big, while keeping the fonts and all the
# same size
F.set_size_inches( (DefaultSize[0]*2, DefaultSize[1]*2) )
Size = F.get_size_inches()
print "Size in Inches", Size
F.savefig("test2.png")
# this results in a 1595x1132 image

# Now make the image twice as big, making all the fonts and lines
# bigger too.

F.set_size_inches( DefaultSize )# resetthe size
Size = F.get_size_inches()
print "Size in Inches", Size
F.savefig("test3.png", dpi = (200)) # change the dpi
# this also results in a 1595x1132 image, but the fonts are larger.

Output:

using MPL version: 0.98.1
DPI: 80
Default size in Inches [ 8.  6.]
Which should result in a 640 x 480 Image
Size in Inches [ 16.  12.]
Size in Inches [ 16.  12.]

Two notes:

  1. The module comments and the actual output differ.

  2. This answer allows easily to combine all three images in one image file to see the difference in sizes.


回答 7

您可以简单地使用(来自matplotlib.figure.Figure):

fig.set_size_inches(width,height)

从Matplotlib 2.0.0开始,对画布的更改将立即可见,因为forward关键字默认为True

如果您只想更改宽度高度而不是两者,则可以使用

fig.set_figwidth(val) 要么 fig.set_figheight(val)

这些也将立即更新您的画布,但仅限于Matplotlib 2.2.0和更高版本。

对于较旧的版本

您需要forward=True明确指定以便实时更新比上面指定的版本更早的画布。请注意,在Matplotlib 1.5.0之前的版本中,set_figwidthand set_figheight函数不支持该forward参数。

You can simply use (from matplotlib.figure.Figure):

fig.set_size_inches(width,height)

As of Matplotlib 2.0.0, changes to your canvas will be visible immediately, as the forward keyword defaults to True.

If you want to just change the width or height instead of both, you can use

fig.set_figwidth(val) or fig.set_figheight(val)

These will also immediately update your canvas, but only in Matplotlib 2.2.0 and newer.

For Older Versions

You need to specify forward=True explicitly in order to live-update your canvas in versions older than what is specified above. Note that the set_figwidth and set_figheight functions don’t support the forward parameter in versions older than Matplotlib 1.5.0.


回答 8

import matplotlib.pyplot as plt
plt.figure(figsize=(20,10))
plt.plot(x,y) ## This is your plot
plt.show()

您还可以使用:

fig, ax = plt.subplots(figsize=(20, 10))
import matplotlib.pyplot as plt
plt.figure(figsize=(20,10))
plt.plot(x,y) ## This is your plot
plt.show()

You can also use:

fig, ax = plt.subplots(figsize=(20, 10))

回答 9

尝试注释掉该fig = ...

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

N = 50
x = np.random.rand(N)
y = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2

fig = plt.figure(figsize=(18, 18))
plt.scatter(x, y, s=area, alpha=0.5)
plt.show()

Try commenting out the fig = ... line

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

N = 50
x = np.random.rand(N)
y = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2

fig = plt.figure(figsize=(18, 18))
plt.scatter(x, y, s=area, alpha=0.5)
plt.show()

回答 10

这对我来说很好:

from matplotlib import pyplot as plt

F = plt.gcf()
Size = F.get_size_inches()
F.set_size_inches(Size[0]*2, Size[1]*2, forward=True) # Set forward to True to resize window along with plot in figure.
plt.show() # or plt.imshow(z_array) if using an animation, where z_array is a matrix or numpy array

这也可能会有所帮助:http : //matplotlib.1069221.n5.nabble.com/Resizing-figure-windows-td11424.html

This works well for me:

from matplotlib import pyplot as plt

F = plt.gcf()
Size = F.get_size_inches()
F.set_size_inches(Size[0]*2, Size[1]*2, forward=True) # Set forward to True to resize window along with plot in figure.
plt.show() # or plt.imshow(z_array) if using an animation, where z_array is a matrix or numpy array

This might also help: http://matplotlib.1069221.n5.nabble.com/Resizing-figure-windows-td11424.html


回答 11

要增加N倍的图形大小,您需要在pl.show()之前插入它:

N = 2
params = pl.gcf()
plSize = params.get_size_inches()
params.set_size_inches( (plSize[0]*N, plSize[1]*N) )

它也可以与ipython notebook一起很好地工作。

To increase size of your figure N times you need to insert this just before your pl.show():

N = 2
params = pl.gcf()
plSize = params.get_size_inches()
params.set_size_inches( (plSize[0]*N, plSize[1]*N) )

It also works well with ipython notebook.


回答 12

由于Matplotlib 本身无法使用公制,因此,如果要以合理的长度单位(例如厘米)指定图形的大小,则可以执行以下操作(来自gns-ank的代码):

def cm2inch(*tupl):
    inch = 2.54
    if isinstance(tupl[0], tuple):
        return tuple(i/inch for i in tupl[0])
    else:
        return tuple(i/inch for i in tupl)

然后,您可以使用:

plt.figure(figsize=cm2inch(21, 29.7))

Since Matplotlib isn’t able to use the metric system natively, if you want to specify the size of your figure in a reasonable unit of length such as centimeters, you can do the following (code from gns-ank):

def cm2inch(*tupl):
    inch = 2.54
    if isinstance(tupl[0], tuple):
        return tuple(i/inch for i in tupl[0])
    else:
        return tuple(i/inch for i in tupl)

Then you can use:

plt.figure(figsize=cm2inch(21, 29.7))

回答 13

即使在绘制图形之后,这也会立即调整图形的大小(至少使用带有matplotlib 1.4.0的Qt4Agg / TkAgg-但不使用MacOSX-):

matplotlib.pyplot.get_current_fig_manager().resize(width_px, height_px)

This resizes the figure immediately even after the figure has been drawn (at least using Qt4Agg/TkAgg – but not MacOSX – with matplotlib 1.4.0):

matplotlib.pyplot.get_current_fig_manager().resize(width_px, height_px)

回答 14

概括和简化psihodelia的答案。如果您想将图形的当前大小更改一个因子sizefactor

import matplotlib.pyplot as plt

# here goes your code

fig_size = plt.gcf().get_size_inches() #Get current size
sizefactor = 0.8 #Set a zoom factor
# Modify the current size by the factor
plt.gcf().set_size_inches(sizefactor * fig_size) 

更改当前大小后,可能需要微调子图布局。您可以在图形窗口GUI中执行此操作,也可以通过命令subplots_adjust进行操作

例如,

plt.subplots_adjust(left=0.16, bottom=0.19, top=0.82)

Generalizing and simplifying psihodelia’s answer. If you want to change the current size of the figure by a factor sizefactor

import matplotlib.pyplot as plt

# here goes your code

fig_size = plt.gcf().get_size_inches() #Get current size
sizefactor = 0.8 #Set a zoom factor
# Modify the current size by the factor
plt.gcf().set_size_inches(sizefactor * fig_size) 

After changing the current size, it might occur that you have to fine tune the subplot layout. You can do that in the figure window GUI, or by means of the command subplots_adjust

For example,

plt.subplots_adjust(left=0.16, bottom=0.19, top=0.82)

回答 15

另一种选择是在matplotlib中使用rc()函数(单位为英寸)

import matplotlib
matplotlib.rc('figure', figsize=[10,5])

Another option, to use the rc() function in matplotlib (the unit is inch)

import matplotlib
matplotlib.rc('figure', figsize=[10,5])

回答 16

您可以通过直接更改图形尺寸

plt.set_figsize(figure=(10, 10))

You directly change the figure size by using

plt.set_figsize(figure=(10, 10))