As far as I know, this is not yet possible in qiskit
, since the plot_state_city
function does not accept an optional argument that would help doing this.
However, this function returns a Figure
object from matplotlib
, which one can access. Thus, it is possible to modify the plot once it has been created with the plot_state_city
option to place the labels where we want.
First of all, we create the circuit:
qc = QuantumCircuit(2)
qc.h(0)
qc.cnot(0, 1)
qc.s(0)
and we create the associated density matrix, were we to apply this circuit on the $|00\rangle$ state:
dm = qi.DensityMatrix.from_instruction(qc)
Since we will need the real and imaginary parts of this matrix, we save them in a list:
arrays = [np.real(dm), np.imag(dm)]
And in order to get beautiful labels, we want their value to be printed using $\LaTeX$. For this, we can use the array_to_latex
function from qiskit.visualize
:
latex_sources = [array_to_latex(array, source=True) for array in arrays]
We also need to create the Figure
object using plot_state_city
:
ax = plot_state_city(dm)
And now the dirty hack begins. You can parse the source using vanilla Python to get the associated $\LaTeX$ labels to the value you want. The code for this is:
for index_source, latex_source in enumerate(latex_sources):
for index_line, line in enumerate(latex_source.split("\n")[3:-2]):
for index_column, value in enumerate(line.split("&")):
# Print label only if it is non-zero
if arrays[index_source][index_line, index_column]:
ax.axes[index_source].text(
index_column,
index_line,
arrays[index_source][index_line, index_column],
"$" + value.replace("\\\\", "").replace("tfrac", "dfrac") + "$"
)
The final complete code is:
import qiskit.quantum_info as qi
from qiskit.visualization import plot_state_city, array_to_latex
def plot_state_city_with_labels(dm):
ax = plot_state_city(dm)
arrays = [np.real(dm), np.imag(dm)]
latex_sources = [array_to_latex(array, source=True) for array in arrays]
offset_x = 0
offset_y = 0
for index_source, latex_source in enumerate(latex_sources):
for index_line, line in enumerate(latex_source.split("\n")[3:-2]):
for index_column, value in enumerate(line.split("&")):
# Print label only if it is non-zero
if arrays[index_source][index_line, index_column]:
ax.axes[index_source].text(
index_column,
index_line,
arrays[index_source][index_line, index_column],
"$" + value.replace("\\\\", "").replace("tfrac", "dfrac") + "$"
)
return ax
qc = QuantumCircuit(2)
qc.h(0)
qc.cnot(0, 1)
qc.s(0)
dm = qi.DensityMatrix.from_instruction(qc)
plot_state_city_with_labels(dm)
which results in the following plot:

However, it might be worth a try to open an issue on the qiskit-terra
GitHub to add such a feature.