<｜begin▁of▁sentence｜>### Instruction:
As a chemical engineer designing a new chemical process, imagine you have a complex network representing various chemical reactions, with nodes labeled as 'Reactant A', 'Reactant B', and 'Product C'. Now, you need to create a duplicate of this network to experiment with different labeling schemes for your reactants and products, without altering the original network structure. How can you use the 'copy' function in the igraph API to achieve this, ensuring that any changes made to the labels in the duplicate network are also reflected in the original network?
### Response:
```python
import igraph as ig
from copy import deepcopy

# Create a graph with 3 vertices
g = ig.Graph(3)

# Add attributes to the graph
g.vs["label"] = ['A', 'B', 'C']

# Make a shallow copy of the graph
g_copy = g.copy()

# For a deep copy, use the deepcopy function
#g_deepcopy = deepcopy(g)

print('Original Graph Labels:', g.vs['label'])
print('Shallow Copy Graph Labels:', g_copy.vs['label'])
# To demonstrate that it's a shallow copy, modifying the copy also modifies the original
g_copy.vs['label'][0] = 'X'
print('Modified Graph Labels:', g.vs['label'])
```
<|EOT|>
